5 #include "GVOWorldMap.h"
10 const double k_scaleStep = 0.125; // 12.5%
11 const double k_minScale = 0.125; // 12.5%
12 const double k_maxScale = 4.00; // 400%
16 bool GVOWorldMap::loadFromFile( const GVOConfig& config )
18 std::wstring filePath;
20 filePath = g_makeFullPath( config.m_mapFileName );
21 if ( !m_mapImage.loadFromFile( filePath.c_str() ) ) {
22 filePath = g_makeFullPath( config.m_defaultMapFileName );
23 if ( !m_mapImage.loadFromFile( filePath.c_str() ) ) {
28 //
\89æ
\91\9c\82Ì
\8d\82\82³
\82Æ
\88Ü
\93x
\82Ì
\94ä
\97¦
\82Ì
\83X
\83P
\81[
\83\8a\83\93\83O
\82Ì
\8aî
\8f\80\82Æ
\82È
\82é
\81B
29 const double mapHeight = m_mapImage.height();
30 m_ratioForImageCoordFromWorldCoord = mapHeight / k_worldHeight;
35 void GVOWorldMap::setViewSize( const SIZE& viewSize )
37 m_viewSize = viewSize;
41 void GVOWorldMap::offsetFocusInViewCoord( const POINT& offset )
43 const double dx = ((double)offset.x / m_viewScale) / m_mapImage.width();
44 const double dy = ((double)offset.y / m_viewScale) / m_mapImage.height();
46 LONG x = m_focusPointInWorldCoord.x + LONG( dx * k_worldWidth );
47 LONG y = m_focusPointInWorldCoord.y + LONG( dy * k_worldHeight );
48 y = max( 0, min( y, k_worldHeight ) );
52 while ( k_worldWidth < x ) {
56 m_focusPointInWorldCoord.x = x;
57 m_focusPointInWorldCoord.y = y;
61 void GVOWorldMap::setConfig( const GVOConfig& config )
63 m_positionUpdated = config.m_traceShipPositionEnabled;
64 m_focusPointInWorldCoord = config.m_initialSurveyCoord;
65 m_shipPointInWorld = config.m_initialSurveyCoord;
66 m_previousDrawPointInWorld = m_shipPointInWorld;
67 m_shipVectorLineEnabled = config.m_shipVectorLineEnabled;
71 void GVOWorldMap::setShipPosition( const POINT& worldCoord, bool isSyncCenter )
74 m_focusPointInWorldCoord = worldCoord;
76 if ( m_shipPointInWorld.x != worldCoord.x
77 || m_shipPointInWorld.y != worldCoord.y ) {
79 m_positionUpdated = true;
80 m_shipPointInWorld = worldCoord;
85 bool GVOWorldMap::zoomIn()
87 double scale = m_viewScale;
88 double step = k_scaleStep;
90 scale = m_viewScale + step;
91 if ( k_maxScale < scale ) {
94 if ( m_viewScale != scale ) {
102 bool GVOWorldMap::zoomOut()
104 double scale = m_viewScale;
105 double step = k_scaleStep;
107 scale = m_viewScale - step;
108 if ( scale < k_minScale ) {
111 if ( m_viewScale != scale ) {
119 void GVOWorldMap::drawMap( HDC hdc, const GVOShip& ship )
121 const SIZE mapSize = scaledMapSize();
122 GVOImage scaledMapImage;
123 GVOImage *mapImage = &m_mapImage;
126 if ( m_viewScale < 1.0 ) {
127 //
\8fk
\8f¬
\89æ
\91\9c\95`
\89æ
\83R
\83X
\83g
\82ð
\8cy
\8c¸
\82·
\82é
\88×
\82É
\83L
\83\83\83b
\83V
\83\85\82ð
\8dì
\90¬
\81B
128 //
\95p
\94É
\82É
\8fk
\8f¬
\94ä
\97¦
\82ð
\95Ï
\8dX
\82·
\82é
\8e\9e\82¾
\82¯
\83R
\83X
\83g
\82ª
\8d\82\82
\95t
\82
\82ª
\81A
129 //
\96w
\82Ç
\82Ì
\8fê
\8d\87\82É
\82¨
\82¢
\82ÄCPU
\95\89\89×
\82ª
\8cy
\8c¸
\82³
\82ê
\82é
\81B
130 if ( !m_reducedMapImageCache.isCompatible(mapSize) ) {
131 m_reducedMapImageCache.stretchCopy( m_mapImage, mapSize );
133 mapImage = &m_reducedMapImageCache;
135 ::SetStretchBltMode( hdc, COLORONCOLOR );
137 HDC hdcMem = ::CreateCompatibleDC( hdc );
140 ::SelectObject( hdcMem, mapImage->bitmapHandle() );
142 const POINT mapTopLeft = mapOriginInView();
144 int xDrawOrigin, yDrawOrigin;
145 xDrawOrigin = mapTopLeft.x;
146 yDrawOrigin = mapTopLeft.y;
148 if ( 0 < xDrawOrigin ) {
149 xDrawOrigin = (xDrawOrigin % mapSize.cx) - mapSize.cx;
151 const int xInitial = xDrawOrigin; //
\8d¶
\92[
\82Ì
\95`
\89æ
\8aJ
\8enx
\8dÀ
\95W
152 int drawn = xInitial; //
\95`
\89æ
\8dÏ
\82Ý
\8dÀ
\95W
154 //
\90¢
\8aE
\92n
\90}
\82ð
\89¡
\82É
\95À
\82×
\82Ä
\95`
\89æ
155 //
\81i
\95`
\89æ
\8dÅ
\93K
\89»
\82Í
\8fÈ
\97ª
\81j
156 while ( drawn < m_viewSize.cx ) {
158 xDrawOrigin, yDrawOrigin,
159 mapSize.cx, mapSize.cy,
162 mapImage->width(), mapImage->height(),
165 xDrawOrigin += mapSize.cx;
170 const POINT shipPointOffset = drawOffsetFromWorldCoord( m_shipPointInWorld );
172 //
\90j
\98H
\97\
\91ª
\90ü
\82ð
\95`
\89æ
173 if ( ship.isVectorEnabled() && m_shipVectorLineEnabled ) {
174 const int penWidth = max( 1, int(1 * m_viewScale) );
175 HPEN courseLinePen = ::CreatePen( PS_SOLID, penWidth, RGB( 255, 0, 255 ) );
176 HGDIOBJ oldPen = ::SelectObject( hdc, courseLinePen );
178 const LONG k_lineLength = k_worldHeight;
179 const POINT reachPointOffset = drawOffsetFromWorldCoord(
180 ship.pointFromOriginWithLength( m_shipPointInWorld, k_lineLength )
183 //
\8c©
\82¦
\82Ä
\82é
\92n
\90}
\89æ
\91\9c\82Ì
\95ª
\82¾
\82¯
\95`
\89æ
\82·
\82é
185 xDrawOrigin = xInitial;
186 while ( drawn < m_viewSize.cx ) {
187 const POINT shipPointInView = {
188 xDrawOrigin + shipPointOffset.x,
189 yDrawOrigin + shipPointOffset.y
191 const POINT reachPointInView = {
192 xDrawOrigin + reachPointOffset.x,
193 yDrawOrigin + reachPointOffset.y
195 ::MoveToEx( hdc, shipPointInView.x, shipPointInView.y, NULL );
196 ::LineTo( hdc, reachPointInView.x, reachPointInView.y );
197 xDrawOrigin += mapSize.cx;
201 ::SelectObject( hdc, oldPen );
202 ::DeleteObject( courseLinePen );
205 //
\8e©
\91D
\82Ì
\88Ê
\92u
\82ð
\95`
\89æ
206 const SIZE shipMarkSize = { 6, 6 };
207 HBRUSH shipBrush = ::CreateSolidBrush( RGB( 51, 238, 153 ) );
208 HGDIOBJ prevBrush = ::SelectObject( hdc, shipBrush );
210 //
\8c©
\82¦
\82Ä
\82é
\92n
\90}
\89æ
\91\9c\82Ì
\95ª
\82¾
\82¯
\95`
\89æ
\82·
\82é
212 xDrawOrigin = xInitial;
213 while ( drawn < m_viewSize.cx ) {
215 xDrawOrigin + shipPointOffset.x - shipMarkSize.cx / 2,
216 yDrawOrigin + shipPointOffset.y - shipMarkSize.cy / 2,
217 xDrawOrigin + shipPointOffset.x + shipMarkSize.cx,
218 yDrawOrigin + shipPointOffset.y + shipMarkSize.cy );
220 xDrawOrigin += mapSize.cx;
223 ::SelectObject( hdc, prevBrush );
224 ::DeleteObject( shipBrush );
227 ::RestoreDC( hdcMem, -1 );
228 ::DeleteDC( hdcMem );
229 ::RestoreDC( hdc, -1 );
233 void GVOWorldMap::updateShipRouteMap( HDC hdc )
235 //
\88Ú
\93®
\82µ
\82Ä
\82¢
\82È
\82¯
\82ê
\82Î
\89½
\82à
\82µ
\82È
\82¢
236 if ( !m_positionUpdated ) {
239 //
\88Ú
\93®
\82µ
\82Ä
\82¢
\82Ä
\82à
\8dq
\98H
\82ð
\8cq
\82°
\82È
\82¢
\82È
\82ç
\95`
\89æ
\82µ
\82È
\82¢
240 if ( !m_linkRoute ) {
241 m_previousDrawPointInWorld = m_shipPointInWorld;
246 const POINT& latestPoint = imageCoordFromWorldCoord( m_shipPointInWorld );
247 const POINT& previousPoint = imageCoordFromWorldCoord( m_previousDrawPointInWorld );
249 //
\95`
\89æ
\8dÀ
\95W
\82ª
\88ê
\8f\8f\82È
\82ç
\89½
\82à
\82µ
\82È
\82¢
250 if ( latestPoint.x == previousPoint.x
251 && latestPoint.y == previousPoint.y ) {
256 //
\8dÅ
\90V
\8dÀ
\95W
\82©
\82ç
\88ê
\82Â
\91O
\82Ì
\8dÀ
\95W
\82Ö
\90ü
\82ð
\88ø
\82
257 //
\90¢
\8aE
\82ð
\8c×
\82®
\8fê
\8d\87\82É
\8dl
\97¶
\82ª
\95K
\97v
\81B
258 //
\88Ú
\93®
\97Ê
\82ª
\88ê
\92è
\82ð
\92´
\82¦
\82½
\82ç
\95`
\89æ
\8f\88\97\9d\82µ
\82È
\82¢
\82æ
\82¤
\82É
\82·
\82é
\82Ì
\82ª
\83X
\83}
\81[
\83g
\82©
\82È
261 //
\90¢
\8aE
\82ð
\8c×
\82¢
\82¾
\82Æ
\82Ý
\82È
\82·è
\87\92l
262 const int k_distanceThreshold = m_mapImage.width() / 2;
264 const LONG xMin = min( latestPoint.x, previousPoint.x );
265 const LONG xMax = max( latestPoint.x, previousPoint.x );
266 const int xDistance = xMax - xMin;
269 HDC hdcMem = ::CreateCompatibleDC( hdc );
272 HPEN hpen = ::CreatePen( PS_SOLID, 1, RGB( 255, 255, 255 ) );
274 ::SelectObject( hdcMem, m_mapImage.bitmapHandle() );
275 ::SelectObject( hdcMem, hpen );
277 if ( k_distanceThreshold < xDistance ) {
278 if ( previousPoint.x < latestPoint.x ) { //
\90¢
\8aE
\82ð
\90¼
\82É
\8cü
\82©
\82Á
\82Ä
\8c×
\82¢
\82¾
279 //
\8d¶
\82Ì
\89æ
\96Ê
\8aO
\82©
\82ç
\8cü
\82©
\82¤
\90ü
\82ð
\95`
\89æ
280 LONG x3 = latestPoint.x - m_mapImage.width();
282 ::MoveToEx( hdcMem, x3, latestPoint.y, NULL );
283 ::LineTo( hdcMem, previousPoint.x, previousPoint.y );
285 //
\89E
\82Ì
\89æ
\96Ê
\8aO
\82É
\8cü
\82©
\82¤
\90ü
\82ð
\95`
\89æ
286 LONG x4 = previousPoint.x + m_mapImage.width();
287 ::MoveToEx( hdcMem, latestPoint.x, latestPoint.y, NULL );
288 ::LineTo( hdcMem, x4, previousPoint.y );
290 else { //
\90¢
\8aE
\82ð
\93\8c\82É
\8cü
\82©
\82Á
\82Ä
\8c×
\82¢
\82¾
291 //
\8d¶
\82Ì
\89æ
\96Ê
\8aO
\82©
\82ç
\8cü
\82©
\82¤
\90ü
\82ð
\95`
\89æ
292 LONG x3 = previousPoint.x - m_mapImage.width();
294 ::MoveToEx( hdcMem, latestPoint.x, latestPoint.y, NULL );
295 ::LineTo( hdcMem, x3, previousPoint.y );
297 //
\89E
\82Ì
\89æ
\96Ê
\8aO
\82É
\8cü
\82©
\82¤
\90ü
\82ð
\95`
\89æ
298 LONG x4 = latestPoint.x + m_mapImage.width();
299 ::MoveToEx( hdcMem, x4, latestPoint.y, NULL );
300 ::LineTo( hdcMem, previousPoint.x, previousPoint.y );
304 //
\8c×
\82ª
\82È
\82¢
\95`
\89æ
305 ::MoveToEx( hdcMem, latestPoint.x, latestPoint.y, NULL );
306 ::LineTo( hdcMem, previousPoint.x, previousPoint.y );
310 ::RestoreDC( hdcMem, -1 );
311 ::DeleteDC( hdcMem );
312 ::DeleteObject( hpen );
314 m_previousDrawPointInWorld = m_shipPointInWorld;
318 void GVOWorldMap::clearShipRoute()
320 const std::wstring fileName = m_mapImage.fileName();
321 m_mapImage.loadFromFile( fileName );
325 POINT GVOWorldMap::mapOriginInView()
327 const POINT viewCenter = viewCenterPoint();
328 const SIZE mapSize = scaledMapSize();
329 const POINT worldPosInView = drawOffsetFromWorldCoord( m_focusPointInWorldCoord );
332 viewCenter.x - worldPosInView.x,
333 viewCenter.y - worldPosInView.y
335 if ( m_viewSize.cx < mapSize.cx ) {
336 while ( 0 < mapTopLeft.x ) {
337 mapTopLeft.x -= mapSize.cx;
345 POINT GVOWorldMap::imageCoordFromWorldCoord( const POINT& worldCoord ) const
347 const double xNormPos = worldCoord.x / (double)k_worldWidth;
348 const double yNormPos = worldCoord.y / (double)k_worldHeight;
349 const POINT worldPosInImage = {
350 LONG( m_mapImage.width() * xNormPos ),
351 LONG( m_mapImage.height() * yNormPos )
353 return worldPosInImage;
356 POINT GVOWorldMap::drawOffsetFromWorldCoord( const POINT&worldCoord ) const
358 const POINT worldPosInImage = imageCoordFromWorldCoord( worldCoord );
359 const POINT drawOffset = {
360 LONG( worldPosInImage.x * m_viewScale ),
361 LONG( worldPosInImage.y * m_viewScale )