3 #include "attributes.h"
17 static QMap
<uint
,uint
> orderMapInit()
21 map
.insert(TYPE(LIGHTS
), 0);
22 map
.insert(TYPE(FOGSIG
), 0);
24 map
.insert(TYPE(CGUSTA
), 1);
25 map
.insert(TYPE(RSCSTA
), 1);
26 map
.insert(SUBTYPE(BUAARE
, 1), 2);
27 map
.insert(SUBTYPE(BUAARE
, 5), 3);
28 map
.insert(SUBTYPE(BUAARE
, 4), 4);
29 map
.insert(SUBTYPE(BUAARE
, 3), 5);
30 map
.insert(SUBTYPE(BUAARE
, 2), 6);
31 map
.insert(SUBTYPE(BUAARE
, 6), 7);
32 map
.insert(SUBTYPE(BUAARE
, 0), 8);
33 map
.insert(TYPE(RDOSTA
), 9);
34 map
.insert(TYPE(RADSTA
), 10);
35 map
.insert(TYPE(RTPBCN
), 11);
36 map
.insert(TYPE(BCNISD
), 12);
37 map
.insert(TYPE(BCNLAT
), 13);
38 map
.insert(TYPE(I_BCNLAT
), 13);
39 map
.insert(TYPE(BCNSAW
), 14);
40 map
.insert(TYPE(BCNSPP
), 15);
41 map
.insert(TYPE(BOYCAR
), 16);
42 map
.insert(TYPE(BOYINB
), 17);
43 map
.insert(TYPE(BOYISD
), 18);
44 map
.insert(TYPE(BOYLAT
), 19);
45 map
.insert(TYPE(I_BOYLAT
), 19);
46 map
.insert(TYPE(BOYSAW
), 20);
47 map
.insert(TYPE(BOYSPP
), 21);
48 map
.insert(TYPE(MORFAC
), 22);
49 map
.insert(TYPE(OFSPLF
), 23);
50 map
.insert(TYPE(OBSTRN
), 24);
51 map
.insert(TYPE(WRECKS
), 25);
52 map
.insert(TYPE(UWTROC
), 26);
53 map
.insert(TYPE(WATTUR
), 27);
54 map
.insert(TYPE(CURENT
), 28);
55 map
.insert(TYPE(PILBOP
), 29);
56 map
.insert(TYPE(SISTAT
), 30);
57 map
.insert(TYPE(I_SISTAT
), 30);
58 map
.insert(TYPE(RDOCAL
), 31);
59 map
.insert(TYPE(I_RDOCAL
), 31);
60 map
.insert(TYPE(I_TRNBSN
), 32);
61 map
.insert(TYPE(HRBFAC
), 33);
62 map
.insert(TYPE(I_HRBFAC
), 33);
63 map
.insert(TYPE(PILPNT
), 34);
64 map
.insert(TYPE(ACHBRT
), 35);
65 map
.insert(TYPE(I_ACHBRT
), 35);
66 map
.insert(TYPE(CRANES
), 36);
67 map
.insert(TYPE(I_CRANES
), 36);
68 map
.insert(TYPE(I_WTWGAG
), 37);
69 map
.insert(TYPE(PYLONS
), 38);
70 map
.insert(TYPE(SLCONS
), 39);
71 map
.insert(TYPE(LNDMRK
), 40);
72 map
.insert(TYPE(SILTNK
), 41);
73 map
.insert(TYPE(LNDELV
), 42);
74 map
.insert(TYPE(SMCFAC
), 43);
75 map
.insert(TYPE(BUISGL
), 44);
77 map
.insert(TYPE(I_DISMAR
), 0xFFFFFFFE);
78 map
.insert(TYPE(SOUNDG
), 0xFFFFFFFF);
83 static QMap
<uint
,uint
> orderMap
= orderMapInit();
85 static uint
order(uint type
)
87 uint st
= ((type
>>16) == BUAARE
) ? type
: (type
& 0xFFFF0000);
88 QMap
<uint
, uint
>::const_iterator
it(orderMap
.find(st
));
89 return (it
== orderMap
.constEnd()) ? (type
>>16) + 512 : it
.value();
92 static void warning(const ISO8211::Field
&FRID
, uint PRIM
)
94 uint RCID
= 0xFFFFFFFF;
95 FRID
.subfield("RCID", &RCID
);
99 qWarning("%u: invalid point feature", RCID
);
102 qWarning("%u: invalid line feature", RCID
);
105 qWarning("%u: invalid area feature", RCID
);
110 static void pointBounds(const Coordinates
&c
, double min
[2], double max
[2])
118 static void rectcBounds(const RectC
&rect
, double min
[2], double max
[2])
120 min
[0] = rect
.left();
121 min
[1] = rect
.bottom();
122 max
[0] = rect
.right();
126 static bool parseNAME(const ISO8211::Field
*f
, quint8
*type
, quint32
*id
,
129 QByteArray
ba(f
->data().at(idx
).at(0).toByteArray());
133 *type
= (quint8
)(*ba
.constData());
134 *id
= UINT32(ba
.constData() + 1);
139 static const ISO8211::Field
*SGXD(const ISO8211::Record
&r
)
141 const ISO8211::Field
*f
;
143 if ((f
= ISO8211::field(r
, "SG2D")))
145 else if ((f
= ISO8211::field(r
, "SG3D")))
151 static bool pointCb(const MapData::Point
*point
, void *context
)
153 QList
<MapData::Point
> *points
= (QList
<MapData::Point
>*)context
;
154 points
->append(*point
);
158 static bool lineCb(const MapData::Line
*line
, void *context
)
160 QList
<MapData::Line
> *lines
= (QList
<MapData::Line
>*)context
;
161 lines
->append(*line
);
165 static bool polygonCb(const MapData::Poly
*polygon
, void *context
)
167 QList
<MapData::Poly
> *polygons
= (QList
<MapData::Poly
>*)context
;
168 polygons
->append(*polygon
);
172 static Coordinates
coordinates(int x
, int y
, uint COMF
)
174 return Coordinates(x
/ (double)COMF
, y
/ (double)COMF
);
177 static Coordinates
point(const ISO8211::Record
&r
, uint COMF
)
179 const ISO8211::Field
*f
= SGXD(r
);
181 return Coordinates();
183 int y
= f
->data().at(0).at(0).toInt();
184 int x
= f
->data().at(0).at(1).toInt();
186 return coordinates(x
, y
, COMF
);
189 static uint
depthLevel(const QByteArray
&ba
)
191 double minDepth
= ba
.isEmpty() ? -1 : ba
.toDouble();
195 else if (minDepth
< 2)
197 else if (minDepth
< 5)
199 else if (minDepth
< 10)
201 else if (minDepth
< 20)
203 else if (minDepth
< 50)
209 static QString
hUnits(uint type
)
229 static QString
sistat(uint type
)
233 return "SS (Port Control)";
239 return "SS (Bridge)";
245 static QString
weed(uint type
)
257 MapData::Point::Point(uint type
, const Coordinates
&c
, const QString
&label
,
258 const QVector
<QByteArray
> ¶ms
) : _type(type
), _pos(c
), _label(label
)
260 _id
= ((quint64
)order(type
))<<32 | (uint
)qHash(c
);
262 if (type
>>16 == I_DISMAR
&& params
.size()) {
263 _label
= hUnits((type
>>8)&0xFF) + " " + QString::fromLatin1(params
.at(0));
264 _type
= SUBTYPE(I_DISMAR
, type
& 0xFF);
265 } else if ((type
>>16 == I_RDOCAL
|| type
>>16 == RDOCAL
) && params
.size() > 1) {
266 if (!params
.at(1).isEmpty())
267 _label
= QString("VHF ") + QString::fromLatin1(params
.at(1));
268 _param
= QVariant(params
.at(0).toDouble());
269 } else if (type
>>16 == CURENT
&& params
.size() > 1) {
270 if (!params
.at(1).isEmpty())
271 _label
= QString::fromLatin1(params
.at(1))
272 + QString::fromUtf8("\xE2\x80\x89kt");
273 _param
= QVariant(params
.at(0).toDouble());
274 } else if (type
>>16 == I_SISTAT
|| type
>>16 == SISTAT
) {
275 if (_label
.isEmpty())
276 _label
= sistat(type
& 0xFF);
277 _type
= TYPE(SISTAT
);
278 } else if (type
>>16 == WEDKLP
) {
279 if (_label
.isEmpty())
280 _label
= weed(type
& 0xFF);
281 } else if (type
>>16 == LNDELV
&& params
.size()) {
282 if (_label
.isEmpty())
283 _label
= QString::fromLatin1(params
.at(0))
284 + QString::fromUtf8("\xE2\x80\x89m");
286 _label
+= "\n(" + QString::fromLatin1(params
.at(0))
291 MapData::Poly::Poly(uint type
, const Polygon
&path
, const QString
&label
,
292 const QVector
<QByteArray
> ¶ms
, uint HUNI
) : _type(type
), _path(path
)
294 if (type
== TYPE(DEPARE
) && params
.size())
295 _type
= SUBTYPE(DEPARE
, depthLevel(params
.at(0)));
296 else if (type
== TYPE(TSSLPT
) && params
.size())
297 _param
= QVariant(params
.at(0).toDouble());
298 else if ((type
== TYPE(BRIDGE
) || type
== TYPE(I_BRIDGE
))
300 double clr
= params
.at(0).toDouble();
302 _label
= QString::fromUtf8("\xE2\x86\x95") + UNIT_SPACE
303 + QString::number(clr
) + UNIT_SPACE
+ hUnits(HUNI
);
305 } else if (type
>>16 == LNDARE
|| type
>>16 == SEAARE
)
309 MapData::Line::Line(uint type
, const QVector
<Coordinates
> &path
,
310 const QString
&label
, const QVector
<QByteArray
> ¶ms
)
311 : _type(type
), _path(path
), _label(label
)
313 if ((type
== TYPE(DEPCNT
) || type
== TYPE(LNDELV
)) && params
.size())
314 _label
= QString::fromLatin1(params
.at(0));
317 RectC
MapData::Line::bounds() const
321 for (int i
= 0; i
< _path
.size(); i
++)
322 b
= b
.united(_path
.at(i
));
327 QVector
<MapData::Sounding
> MapData::soundings(const ISO8211::Record
&r
,
328 uint COMF
, uint SOMF
)
331 const ISO8211::Field
*f
= ISO8211::field(r
, "SG3D");
333 return QVector
<Sounding
>();
335 s
.reserve(f
->data().size());
336 for (int i
= 0; i
< f
->data().size(); i
++) {
337 int y
= f
->data().at(i
).at(0).toInt();
338 int x
= f
->data().at(i
).at(1).toInt();
339 int z
= f
->data().at(i
).at(2).toInt();
340 s
.append(Sounding(coordinates(x
, y
, COMF
), z
/ (double)SOMF
));
346 QVector
<MapData::Sounding
> MapData::soundingGeometry(const ISO8211::Record
&r
,
347 const RecordMap
&vi
, const RecordMap
&vc
, uint COMF
, uint SOMF
)
351 RecordMapIterator it
;
353 const ISO8211::Field
*FSPT
= ISO8211::field(r
, "FSPT");
354 if (!FSPT
|| FSPT
->data().at(0).size() != 4)
355 return QVector
<Sounding
>();
357 if (!parseNAME(FSPT
, &type
, &id
))
358 return QVector
<Sounding
>();
360 if (type
== RCNM_VI
) {
362 if (it
== vi
.constEnd())
363 return QVector
<Sounding
>();
364 } else if (type
== RCNM_VC
) {
366 if (it
== vc
.constEnd())
367 return QVector
<Sounding
>();
369 return QVector
<Sounding
>();
371 return soundings(it
.value(), COMF
, SOMF
);
374 Coordinates
MapData::pointGeometry(const ISO8211::Record
&r
,
375 const RecordMap
&vi
, const RecordMap
&vc
, uint COMF
)
379 RecordMapIterator it
;
381 const ISO8211::Field
*FSPT
= ISO8211::field(r
, "FSPT");
382 if (!FSPT
|| FSPT
->data().at(0).size() != 4)
383 return Coordinates();
385 if (!parseNAME(FSPT
, &type
, &id
))
386 return Coordinates();
388 if (type
== RCNM_VI
) {
390 if (it
== vi
.constEnd())
391 return Coordinates();
392 } else if (type
== RCNM_VC
) {
394 if (it
== vc
.constEnd())
395 return Coordinates();
397 return Coordinates();
399 return point(it
.value(), COMF
);
402 QVector
<Coordinates
> MapData::lineGeometry(const ISO8211::Record
&r
,
403 const RecordMap
&vc
, const RecordMap
&ve
, uint COMF
)
405 QVector
<Coordinates
> path
;
411 const ISO8211::Field
*FSPT
= ISO8211::field(r
, "FSPT");
412 if (!FSPT
|| FSPT
->data().at(0).size() != 4)
413 return QVector
<Coordinates
>();
415 for (int i
= 0; i
< FSPT
->data().size(); i
++) {
416 if (!parseNAME(FSPT
, &type
, &id
, i
) || type
!= RCNM_VE
)
417 return QVector
<Coordinates
>();
418 ORNT
= FSPT
->data().at(i
).at(1).toUInt();
420 RecordMapIterator it
= ve
.find(id
);
421 if (it
== ve
.constEnd())
422 return QVector
<Coordinates
>();
423 const ISO8211::Record
&FRID
= it
.value();
424 const ISO8211::Field
*VRPT
= ISO8211::field(FRID
, "VRPT");
425 if (!VRPT
|| VRPT
->data().size() != 2)
426 return QVector
<Coordinates
>();
428 for (int j
= 0; j
< 2; j
++) {
429 if (!parseNAME(VRPT
, &type
, &id
, j
) || type
!= RCNM_VC
)
430 return QVector
<Coordinates
>();
432 RecordMapIterator jt
= vc
.find(id
);
433 if (jt
== vc
.constEnd())
434 return QVector
<Coordinates
>();
435 c
[j
] = point(jt
.value(), COMF
);
437 return QVector
<Coordinates
>();
440 const ISO8211::Field
*vertexes
= SGXD(FRID
);
444 for (int j
= vertexes
->data().size() - 1; j
>= 0; j
--) {
445 const QVector
<QVariant
> &cv
= vertexes
->data().at(j
);
446 path
.append(coordinates(cv
.at(1).toInt(), cv
.at(0).toInt(),
454 for (int j
= 0; j
< vertexes
->data().size(); j
++) {
455 const QVector
<QVariant
> &cv
= vertexes
->data().at(j
);
456 path
.append(coordinates(cv
.at(1).toInt(), cv
.at(0).toInt(),
467 Polygon
MapData::polyGeometry(const ISO8211::Record
&r
, const RecordMap
&vc
,
468 const RecordMap
&ve
, uint COMF
)
471 QVector
<Coordinates
> v
;
477 const ISO8211::Field
*FSPT
= ISO8211::field(r
, "FSPT");
478 if (!FSPT
|| FSPT
->data().at(0).size() != 4)
481 for (int i
= 0; i
< FSPT
->data().size(); i
++) {
482 if (!parseNAME(FSPT
, &type
, &id
, i
) || type
!= RCNM_VE
)
484 ORNT
= FSPT
->data().at(i
).at(1).toUInt();
485 USAG
= FSPT
->data().at(i
).at(2).toUInt();
487 if (USAG
== 2 && path
.isEmpty()) {
492 RecordMapIterator it
= ve
.find(id
);
493 if (it
== ve
.constEnd())
495 const ISO8211::Record
&FRID
= it
.value();
496 const ISO8211::Field
*VRPT
= ISO8211::field(FRID
, "VRPT");
497 if (!VRPT
|| VRPT
->data().size() != 2)
500 for (int j
= 0; j
< 2; j
++) {
501 if (!parseNAME(VRPT
, &type
, &id
, j
) || type
!= RCNM_VC
)
504 RecordMapIterator jt
= vc
.find(id
);
505 if (jt
== vc
.constEnd())
507 c
[j
] = point(jt
.value(), COMF
);
512 const ISO8211::Field
*vertexes
= SGXD(FRID
);
516 v
.append(Coordinates());
518 for (int j
= vertexes
->data().size() - 1; j
>= 0; j
--) {
519 const QVector
<QVariant
> &cv
= vertexes
->data().at(j
);
520 v
.append(coordinates(cv
.at(1).toInt(), cv
.at(0).toInt(),
525 v
.append(Coordinates());
530 v
.append(Coordinates());
532 for (int j
= 0; j
< vertexes
->data().size(); j
++) {
533 const QVector
<QVariant
> &cv
= vertexes
->data().at(j
);
534 v
.append(coordinates(cv
.at(1).toInt(), cv
.at(0).toInt(),
539 v
.append(Coordinates());
543 if (USAG
== 2 && v
.first() == v
.last()) {
555 MapData::Attr
MapData::pointAttr(const ISO8211::Record
&r
, uint OBJL
)
558 QVector
<QByteArray
> params(2);
561 const ISO8211::Field
*ATTF
= ISO8211::field(r
, "ATTF");
562 if (!(ATTF
&& ATTF
->data().at(0).size() == 2))
565 for (int i
= 0; i
< ATTF
->data().size(); i
++) {
566 const QVector
<QVariant
> &av
= ATTF
->data().at(i
);
567 uint key
= av
.at(0).toUInt();
570 label
= QString::fromLatin1(av
.at(1).toByteArray());
572 if ((OBJL
== HRBFAC
&& key
== CATHAF
)
573 || (OBJL
== I_HRBFAC
&& key
== I_CATHAF
)
574 || (OBJL
== LNDMRK
&& key
== CATLMK
)
575 || (OBJL
== WRECKS
&& key
== CATWRK
)
576 || (OBJL
== MORFAC
&& key
== CATMOR
)
577 || (OBJL
== UWTROC
&& key
== WATLEV
)
578 || (OBJL
== BUAARE
&& key
== CATBUA
)
579 || (OBJL
== SMCFAC
&& key
== CATSCF
)
580 || (OBJL
== BUISGL
&& key
== FUNCTN
)
581 || (OBJL
== WATTUR
&& key
== CATWAT
)
582 || (OBJL
== SISTAT
&& key
== CATSIT
)
583 || (OBJL
== I_SISTAT
&& key
== I_CATSIT
)
584 || (OBJL
== RDOCAL
&& key
== TRAFIC
)
585 || (OBJL
== I_RDOCAL
&& key
== TRAFIC
)
586 || (OBJL
== SILTNK
&& key
== CATSIL
)
587 || (OBJL
== WEDKLP
&& key
== CATWED
))
588 subtype
= av
.at(1).toByteArray().toUInt();
589 else if (OBJL
== I_DISMAR
&& key
== CATDIS
)
590 subtype
|= av
.at(1).toByteArray().toUInt();
591 else if (OBJL
== I_DISMAR
&& key
== I_HUNITS
)
592 subtype
|= av
.at(1).toByteArray().toUInt() << 8;
594 if ((OBJL
== I_DISMAR
&& key
== I_WTWDIS
)
595 || (OBJL
== RDOCAL
&& key
== ORIENT
)
596 || (OBJL
== I_RDOCAL
&& key
== ORIENT
)
597 || (OBJL
== CURENT
&& key
== ORIENT
)
598 || (OBJL
== LNDELV
&& key
== ELEVAT
))
599 params
[0] = av
.at(1).toByteArray();
600 if ((OBJL
== I_RDOCAL
&& key
== COMCHA
)
601 || (OBJL
== RDOCAL
&& key
== COMCHA
)
602 || (OBJL
== CURENT
&& key
== CURVEL
))
603 params
[1] = av
.at(1).toByteArray();
606 return Attr(subtype
, label
, params
);
609 MapData::Attr
MapData::lineAttr(const ISO8211::Record
&r
, uint OBJL
)
612 QVector
<QByteArray
> params(1);
615 const ISO8211::Field
*ATTF
= ISO8211::field(r
, "ATTF");
616 if (!(ATTF
&& ATTF
->data().at(0).size() == 2))
619 for (int i
= 0; i
< ATTF
->data().size(); i
++) {
620 const QVector
<QVariant
> &av
= ATTF
->data().at(i
);
621 uint key
= av
.at(0).toUInt();
624 label
= QString::fromLatin1(av
.at(1).toByteArray());
626 if ((OBJL
== RECTRC
|| OBJL
== RCRTCL
) && key
== CATTRK
)
627 subtype
= av
.at(1).toByteArray().toUInt();
629 if ((OBJL
== DEPCNT
&& key
== VALDCO
)
630 || (OBJL
== LNDELV
&& key
== ELEVAT
))
631 params
[0] = av
.at(1).toByteArray();
634 return Attr(subtype
, label
, params
);
637 MapData::Attr
MapData::polyAttr(const ISO8211::Record
&r
, uint OBJL
)
640 QVector
<QByteArray
> params(1);
643 const ISO8211::Field
*ATTF
= ISO8211::field(r
, "ATTF");
644 if (!(ATTF
&& ATTF
->data().at(0).size() == 2))
647 for (int i
= 0; i
< ATTF
->data().size(); i
++) {
648 const QVector
<QVariant
> &av
= ATTF
->data().at(i
);
649 uint key
= av
.at(0).toUInt();
652 label
= QString::fromLatin1(av
.at(1).toByteArray());
654 if ((OBJL
== RESARE
&& key
== CATREA
)
655 || (OBJL
== I_RESARE
&& key
== CATREA
)
656 || (OBJL
== ACHARE
&& key
== CATACH
)
657 || (OBJL
== I_ACHARE
&& key
== I_CATACH
)
658 || (OBJL
== HRBFAC
&& key
== CATHAF
)
659 || (OBJL
== MARKUL
&& key
== CATMFA
)
660 || (OBJL
== I_BERTHS
&& key
== I_CATBRT
))
661 subtype
= av
.at(1).toByteArray().toUInt();
662 else if ((OBJL
== RESARE
&& key
== RESTRN
)
663 || (OBJL
== I_RESARE
&& key
== I_RESTRN
)) {
664 if (av
.at(1).toByteArray().toUInt() == 1)
666 if (av
.at(1).toByteArray().toUInt() == 7)
670 if ((OBJL
== TSSLPT
&& key
== ORIENT
)
671 || (OBJL
== DEPARE
&& key
== DRVAL1
))
672 params
[0] = av
.at(1).toByteArray();
673 if ((OBJL
== BRIDGE
&& key
== VERCLR
)
674 || (OBJL
== I_BRIDGE
&& key
== VERCLR
))
675 params
[0] = av
.at(1).toByteArray();
678 return Attr(subtype
, label
, params
);
681 MapData::Point
*MapData::pointObject(const Sounding
&s
)
683 return new Point(TYPE(SOUNDG
), s
.c
, QString::number(s
.depth
),
684 QVector
<QByteArray
>());
687 MapData::Point
*MapData::pointObject(const ISO8211::Record
&r
,
688 const RecordMap
&vi
, const RecordMap
&vc
, uint COMF
, uint OBJL
)
690 Coordinates
c(pointGeometry(r
, vi
, vc
, COMF
));
691 Attr
attr(pointAttr(r
, OBJL
));
693 return (c
.isNull() ? 0 : new Point(SUBTYPE(OBJL
,attr
.subtype()), c
,
694 attr
.label(), attr
.params()));
697 MapData::Line
*MapData::lineObject(const ISO8211::Record
&r
,
698 const RecordMap
&vc
, const RecordMap
&ve
, uint COMF
, uint OBJL
)
700 QVector
<Coordinates
> path(lineGeometry(r
, vc
, ve
, COMF
));
701 Attr
attr(lineAttr(r
, OBJL
));
703 return (path
.isEmpty() ? 0 : new Line(SUBTYPE(OBJL
, attr
.subtype()), path
,
704 attr
.label(), attr
.params()));
707 MapData::Poly
*MapData::polyObject(const ISO8211::Record
&r
,
708 const RecordMap
&vc
, const RecordMap
&ve
, uint COMF
, uint OBJL
, uint HUNI
)
710 Polygon
path(polyGeometry(r
, vc
, ve
, COMF
));
711 Attr
attr(polyAttr(r
, OBJL
));
713 return (path
.isEmpty() ? 0 : new Poly(SUBTYPE(OBJL
, attr
.subtype()), path
,
714 attr
.label(), attr
.params(), HUNI
));
717 bool MapData::processRecord(const ISO8211::Record
&record
,
718 QVector
<ISO8211::Record
> &fe
, RecordMap
&vi
, RecordMap
&vc
, RecordMap
&ve
,
719 RecordMap
&vf
, uint
&COMF
, uint
&SOMF
, uint
&HUNI
)
721 if (record
.size() < 2)
724 const ISO8211::Field
&f
= record
.at(1);
725 const QByteArray
&ba
= f
.tag();
728 if (f
.data().at(0).size() < 2)
730 int RCNM
= f
.data().at(0).at(0).toInt();
731 uint RCID
= f
.data().at(0).at(1).toUInt();
735 vi
.insert(RCID
, record
);
738 vc
.insert(RCID
, record
);
741 ve
.insert(RCID
, record
);
744 vf
.insert(RCID
, record
);
749 } else if (ba
== "FRID") {
751 } else if (ba
== "DSPM") {
752 if (!(f
.subfield("COMF", &COMF
) && f
.subfield("SOMF", &SOMF
)))
754 if (!f
.subfield("HUNI", &HUNI
))
761 MapData::MapData(const QString
&path
)
763 RecordMap vi
, vc
, ve
, vf
;
764 QVector
<ISO8211::Record
> fe
;
766 ISO8211::Record record
;
767 uint PRIM
, OBJL
, COMF
= 1, SOMF
= 1, HUNI
= 1;
771 double min
[2], max
[2];
776 while (ddf
.readRecord(record
))
777 if (!processRecord(record
, fe
, vi
, vc
, ve
, vf
, COMF
, SOMF
, HUNI
))
778 qWarning("Invalid S-57 record");
780 for (int i
= 0; i
< fe
.size(); i
++) {
781 const ISO8211::Record
&r
= fe
.at(i
);
782 const ISO8211::Field
&f
= r
.at(1);
784 if (f
.data().at(0).size() < 5)
786 PRIM
= f
.data().at(0).at(2).toUInt();
787 OBJL
= f
.data().at(0).at(4).toUInt();
791 if (OBJL
== SOUNDG
) {
792 QVector
<Sounding
> s(soundingGeometry(r
, vi
, vc
, COMF
, SOMF
));
793 for (int i
= 0; i
< s
.size(); i
++) {
794 point
= pointObject(s
.at(i
));
795 pointBounds(point
->pos(), min
, max
);
796 _points
.Insert(min
, max
, point
);
799 if ((point
= pointObject(r
, vi
, vc
, COMF
, OBJL
))) {
800 pointBounds(point
->pos(), min
, max
);
801 _points
.Insert(min
, max
, point
);
807 if ((line
= lineObject(r
, vc
, ve
, COMF
, OBJL
))) {
808 rectcBounds(line
->bounds(), min
, max
);
809 _lines
.Insert(min
, max
, line
);
814 if ((poly
= polyObject(r
, vc
, ve
, COMF
, OBJL
, HUNI
))) {
815 rectcBounds(poly
->bounds(), min
, max
);
816 _areas
.Insert(min
, max
, poly
);
826 LineTree::Iterator lit
;
827 for (_lines
.GetFirst(lit
); !_lines
.IsNull(lit
); _lines
.GetNext(lit
))
828 delete _lines
.GetAt(lit
);
830 PolygonTree::Iterator ait
;
831 for (_areas
.GetFirst(ait
); !_areas
.IsNull(ait
); _areas
.GetNext(ait
))
832 delete _areas
.GetAt(ait
);
834 PointTree::Iterator pit
;
835 for (_points
.GetFirst(pit
); !_points
.IsNull(pit
); _points
.GetNext(pit
))
836 delete _points
.GetAt(pit
);
839 void MapData::points(const RectC
&rect
, QList
<Point
> *points
) const
841 double min
[2], max
[2];
843 rectcBounds(rect
, min
, max
);
844 _points
.Search(min
, max
, pointCb
, points
);
847 void MapData::lines(const RectC
&rect
, QList
<Line
> *lines
) const
849 double min
[2], max
[2];
851 rectcBounds(rect
, min
, max
);
852 _lines
.Search(min
, max
, lineCb
, lines
);
855 void MapData::polygons(const RectC
&rect
, QList
<Poly
> *polygons
) const
857 double min
[2], max
[2];
859 rectcBounds(rect
, min
, max
);
860 _areas
.Search(min
, max
, polygonCb
, polygons
);