1822 #include #include #include #include #include #include #include "gshhs.h" #define LEVEL_LAND 1 #define LEVEL_LAKE 2 #define LEVEL_ISLAND_IN_LAKE 3 #define LEVEL_POND_IN_ISLAND_IN_LAKE 4 typedef struct { double lon; double lat; } MAP_POINT; typedef struct mapPoly { char level; unsigned short nPoints; MAP_POINT *points; struct mapPoly *next; } MAP_POLY; MAP_POLY *mapData = NULL; HINSTANCE hInst; HWND hwndStatus; int statusHeight; BOOL ReadMapData(void) { FILE *f; double w, e, s, n, area, lon, lat; char source; int i; int max_east = 270000000; struct GSHHS h; struct GSHHS_POINT p; MAP_POLY *newPoly, *prevPoly = NULL; if (! (f = fopen("d:/Graphics/GIS/GSHHS/gshhs_l.b", "rb"))) { MessageBox(NULL, "Missing map data file", "DrawMap", MB_OK | MB_ICONERROR); return FALSE; } while (fread((void *)&h, (size_t)sizeof (struct GSHHS), (size_t)1, f) == 1) { h.id = swabi4 ((unsigned int)h.id); h.n = swabi4 ((unsigned int)h.n); h.level = swabi4 ((unsigned int)h.level); h.west = swabi4 ((unsigned int)h.west); h.east = swabi4 ((unsigned int)h.east); h.south = swabi4 ((unsigned int)h.south); h.north = swabi4 ((unsigned int)h.north); h.area = swabi4 ((unsigned int)h.area); h.greenwich = swabi2 ((unsigned int)h.greenwich); h.source = swabi2 ((unsigned int)h.source); newPoly = (MAP_POLY *)malloc(sizeof(MAP_POLY)); newPoly->level = (char)h.level; newPoly->nPoints = (unsigned short)h.n; newPoly->points = (MAP_POINT *)malloc(sizeof(MAP_POINT) * h.n); newPoly->next = NULL; w = h.west * 1.0e-6; e = h.east * 1.0e-6; s = h.south * 1.0e-6; n = h.north * 1.0e-6; source = (h.source == 1) ? 'W' : 'C'; area = 0.1 * h.area; for (i = 0; i < h.n; i++) { if (fread ((void *)&p, (size_t)sizeof(struct GSHHS_POINT), (size_t)1, f) != 1) { MBPrintf("DrawMap", "Error reading file for polygon %d, point %d.\n", h.id, i); return FALSE; } p.x = swabi4 ((unsigned int)p.x); p.y = swabi4 ((unsigned int)p.y); newPoly->points[i].lon = (h.greenwich && p.x > max_east) ? p.x * 1.0e-6 - 360.0 : p.x * 1.0e-6; newPoly->points[i].lat = p.y * 1.0e-6; } if (! mapData) mapData = newPoly; if (prevPoly) prevPoly->next = newPoly; prevPoly = newPoly; max_east = 180000000; } fclose(f); return TRUE; } BOOL DrawMap(HWND hwnd, HDC hdc) { MAP_POLY *mapPoly; POINT *dPoints; RECT rect; HBRUSH hBrush; HPEN hPen; double xScaleFact, yScaleFact; int i; BOOL retVal = TRUE; COLORREF color; ShowStatus(hwndStatus, 0, "Processing..."); GetClientRect(hwnd, &rect); xScaleFact = (double)rect.right / 360.0; yScaleFact = (300.0 * ((double)rect.right / 600.0)) / 180.0; rect.bottom -= statusHeight; hBrush = CreateSolidBrush(0x00ffd0d0); FillRect(hdc, &rect, hBrush); DeleteObject(hBrush); for (mapPoly = mapData; mapPoly; mapPoly = mapPoly->next) { dPoints = (POINT *)malloc(sizeof(POINT) * (int)(mapPoly->nPoints)); for (i = 0; i < (int)mapPoly->nPoints; i++) { dPoints[i].x = (mapPoly->points[i].lon * xScaleFact); dPoints[i].y = (rect.bottom / 2) - (mapPoly->points[i].lat * yScaleFact); } switch (mapPoly->level) { case LEVEL_LAND: color = 0x00209020; break; case LEVEL_LAKE: color = 0x00b00000; break; case LEVEL_ISLAND_IN_LAKE: color = 0x00209020; break; case LEVEL_POND_IN_ISLAND_IN_LAKE: color = 0x00b00000; break; } hBrush = SelectObject(hdc, CreateSolidBrush(color)); hPen = SelectObject(hdc, CreatePen(PS_SOLID, 0, color)); if (! Polygon(hdc, dPoints, (int)mapPoly->nPoints)) { DeleteObject(SelectObject(hdc, hBrush)); DeleteObject(SelectObject(hdc, hPen)); free(dPoints); MBPrintf("DrawMap", "Polygon overflow: %d points", mapPoly->nPoints); retVal = FALSE; goto end; } DeleteObject(SelectObject(hdc, hBrush)); DeleteObject(SelectObject(hdc, hPen)); free(dPoints); } end: ShowStatus(hwndStatus, 0, "Done"); return retVal; } LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps; RECT rect; BOOL r; int x, y; switch (msg) { case WM_CREATE: hwndStatus = CreateStatusWnd(hInst, hwnd, 2); GetWindowRect(hwndStatus, &rect); statusHeight = rect.bottom - rect.top; x = (int)(((LPCREATESTRUCT)lParam)->x); y = (int)(((LPCREATESTRUCT)lParam)->y); MoveWindow(hwnd, x, y, 600 + (GetSystemMetrics(SM_CXSIZEFRAME) * 2), 300 + statusHeight + GetSystemMetrics(SM_CYCAPTION) + (GetSystemMetrics(SM_CYSIZEFRAME) * 2), TRUE); return 0; case WM_SIZE: SendMessage(hwndStatus, WM_SIZE, wParam, lParam); SetStatusParts(hwndStatus, 2); return 0; case WM_PAINT: hdc = BeginPaint(hwnd, &ps); r = DrawMap(hwnd, hdc); EndPaint(hwnd, &ps); if (! r) exit(1); return 0; case WM_DESTROY: PostQuitMessage(0); return 0; } return DefWindowProc(hwnd,msg,wParam,lParam); } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) { WNDCLASS wc; HWND hwnd; MSG msg; if (! ReadMapData()) return 0; hInst = hInstance; wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = 0; wc.hInstance = hInstance; wc.hIcon = LoadIcon(hInstance, IDI_WINLOGO); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1); wc.lpszMenuName = NULL; wc.lpszClassName = "MainWndClass"; if (! RegisterClass(&wc)) return 0; hwnd = CreateWindow( "MainWndClass", "DrawMap", WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, 0, 600, 340, NULL, NULL, hInstance, NULL); ShowWindow(hwnd, nCmdShow); while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } . 0