4 XCSoar Glide Computer - http://www.xcsoar.org/
5 Copyright (C) 2000-2013 The XCSoar Project
6 A detailed list of copyright holders can be found in the file "AUTHORS".
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 #include "Topography/TopographyFile.hpp"
25 #include "Topography/XShape.hpp"
26 #include "Projection/WindowProjection.hpp"
33 TopographyFile::TopographyFile(struct zzip_dir
*_dir
, const char *filename
,
35 fixed _label_threshold
,
36 fixed _important_label_threshold
,
38 int _label_field
, int _icon
,
40 :dir(_dir
), first(NULL
),
41 label_field(_label_field
), icon(_icon
),
42 pen_width(_pen_width
),
43 color(thecolor
), scale_threshold(_threshold
),
44 label_threshold(_label_threshold
),
45 important_label_threshold(_important_label_threshold
),
46 cache_bounds(GeoBounds::Invalid())
48 if (msShapefileOpen(&file
, "rb", dir
, filename
, 0) == -1)
51 if (file
.numshapes
== 0) {
52 msShapefileClose(&file
);
56 shapes
.ResizeDiscard(file
.numshapes
);
57 std::fill(shapes
.begin(), shapes
.end(), ShapeList(NULL
));
65 TopographyFile::~TopographyFile()
71 msShapefileClose(&file
);
80 TopographyFile::ClearCache()
82 for (auto i
= shapes
.begin(), end
= shapes
.end(); i
!= end
; ++i
) {
92 ConvertRect(const GeoBounds
&br
)
95 dest
.minx
= (double)br
.GetWest().Degrees();
96 dest
.maxx
= (double)br
.GetEast().Degrees();
97 dest
.miny
= (double)br
.GetSouth().Degrees();
98 dest
.maxy
= (double)br
.GetNorth().Degrees();
103 TopographyFile::Update(const WindowProjection
&map_projection
)
108 if (map_projection
.GetMapScale() > scale_threshold
)
109 /* not visible, don't update cache now */
112 const GeoBounds screenRect
=
113 map_projection
.GetScreenBounds();
114 if (cache_bounds
.IsValid() && cache_bounds
.IsInside(screenRect
))
115 /* the cache is still fresh */
118 cache_bounds
= map_projection
.GetScreenBounds().Scale(fixed(2));
120 rectObj deg_bounds
= ConvertRect(cache_bounds
);
122 // Test which shapes are inside the given bounds and save the
123 // status to file.status
124 msShapefileWhichShapes(&file
, dir
, deg_bounds
, 0);
126 // If not a single shape is inside the bounds
128 // ... clear the whole buffer
133 // Iterate through the shapefile entries
134 const ShapeList
**current
= &first
;
135 auto it
= shapes
.begin();
136 for (int i
= 0; i
< file
.numshapes
; ++i
, ++it
) {
137 if (!msGetBit(file
.status
, i
)) {
138 // If the shape is outside the bounds
139 // delete the shape from the cache
143 // is inside the bounds
144 if (it
->shape
== NULL
)
145 // shape isn't cached yet -> cache the shape
146 it
->shape
= new XShape(&file
, i
, label_field
);
147 // update list pointer
152 // end of list marker
160 TopographyFile::LoadAll()
162 // Iterate through the shapefile entries
163 const ShapeList
**current
= &first
;
164 auto it
= shapes
.begin();
165 for (int i
= 0; i
< file
.numshapes
; ++i
, ++it
) {
166 if (it
->shape
== NULL
)
167 // shape isn't cached yet -> cache the shape
168 it
->shape
= new XShape(&file
, i
, label_field
);
169 // update list pointer
173 // end of list marker
180 TopographyFile::GetSkipSteps(fixed map_scale
) const
182 if (map_scale
* 4 > scale_threshold
* 3)
184 if (map_scale
* 2 > scale_threshold
)
186 if (map_scale
* 4 > scale_threshold
)
194 TopographyFile::GetThinningLevel(fixed map_scale
) const
196 if (map_scale
* 2 > scale_threshold
)
198 if (map_scale
* 3 > scale_threshold
)
200 if (map_scale
* 4 > scale_threshold
)
207 TopographyFile::GetMinimumPointDistance(unsigned level
) const
211 return (unsigned)(fixed(4) * scale_threshold
/ 30);
213 return (unsigned)(fixed(6) * scale_threshold
/ 30);
215 return (unsigned)(fixed(9) * scale_threshold
/ 30);