2000 /* * MapPlot * * Simple map drawing program for MWDB-II/WDB-II data * */ #include #include #include #include #include #include #include #include #include "mapplot.h" #include "wdb-ii.h" #include "fsbox.h" BOOL ReadMap(VARS *v, char *name) { FILE *f; HDR h; DPOINT p; MAP_POLY *newPoly; char tmp[1024]; int i; sprintf(tmp, "d:/Graphics/GIS/MWDB-II/mw%s.vec", name); if (! (f = fopen(tmp, "rb"))) { MBPrintf("MapPlot", "Couldn't open data file '%s.vec'", name); return FALSE; } while (fread((void *)&h, (size_t)sizeof(HDR), (size_t)1, f) == 1) { if ((int)h.np == 0) { fclose(f); return TRUE; } newPoly = (MAP_POLY *)malloc(sizeof(MAP_POLY)); newPoly->feature = (char)h.feature; newPoly->nPoints = (unsigned short)h.np; if ((int)h.np == 0) { MBPrintf("", "fan"); exit(1); } newPoly->points = (MAP_POINT *)malloc(sizeof(MAP_POINT) * (int)h.np); newPoly->next = NULL; for (i = 0; i < (int)h.np; i++) { if (fread ((void *)&p, (size_t)sizeof(DPOINT), (size_t)1, f) != 1) { fclose(f); MBPrintf("MapPlot", "Error reading data"); return FALSE; } newPoly->points[i].lon = p.lon / 60.0 * 100; newPoly->points[i].lat = p.lat / 60.0 * 100; } if (! v->mapData) v->mapData = newPoly; if (v->prevPoly) v->prevPoly->next = newPoly; v->prevPoly = newPoly; } fclose(f); return TRUE; } BOOL ReadMaps(VARS *v) { char *names[] = {"coast", "nation", "state", "island", "lake", "river", NULL}; char *name; int i; for (i = 0; name = names[i]; i++) { if (! ReadMap(v, name)) return FALSE; } return TRUE; } BOOL DrawMap(VARS *v, HDC hdc) { MAP_POLY *mapPoly; POINT *dPoints; RECT rect; HBRUSH hBrush; HPEN hPen; COLORREF color; HRGN hRgn; double origXOff, origYOff; int i; ShowStatus(v->hwndStatus, 0, "Processing..."); GetClientRect(v->hwndMain, &rect); hRgn = SelectObject(hdc, CreateRectRgn(0, 0, rect.right, rect.bottom - (v->statusHeight + 42))); SelectClipRgn(hdc, hRgn); hBrush = CreateSolidBrush(v->colors[0]); FillRect (hdc, &rect, hBrush); DeleteObject(hBrush); SetMapMode(hdc, MM_ISOTROPIC); SetWindowExtEx(hdc, 18000, 9000, NULL); SetViewportExtEx(hdc, (rect.right / 2) * v->zoom, (-rect.bottom / 2) * v->zoom, NULL); SetViewportOrgEx(hdc, rect.right / 2, (rect.bottom - (v->statusHeight + 42)) / 2, NULL); origXOff = v->origLon * 100; origYOff = v->origLat * 100; for (mapPoly = v->mapData; mapPoly; mapPoly = mapPoly->next) { switch (mapPoly->feature) { case FEAT_COAST: if (! (v->shwFeatures & SHW_COAST)) continue; color = v->colors[1]; break; case FEAT_COUNTRY: if (! (v->shwFeatures & SHW_COUNTRY)) continue; color = v->colors[2]; break; case FEAT_STATE: if (! (v->shwFeatures & SHW_STATE)) continue; color = v->colors[3]; break; case FEAT_ISLAND: if (! (v->shwFeatures & SHW_ISLAND)) continue; color = v->colors[4]; break; case FEAT_LAKE: if (! (v->shwFeatures & SHW_LAKE)) continue; color = v->colors[5]; break; case FEAT_RIVER: if (! (v->shwFeatures & SHW_RIVER)) continue; color = v->colors[6]; break; default: continue; } dPoints = (POINT *)malloc(sizeof(POINT) * (int)mapPoly->nPoints); for (i = 0; i < (int)mapPoly->nPoints; i++) { dPoints[i].x = mapPoly->points[i].lon - origXOff; dPoints[i].y = mapPoly->points[i].lat - origYOff; } hBrush = SelectObject(hdc, CreateSolidBrush(color)); hPen = SelectObject(hdc, CreatePen(PS_SOLID, 0, color)); if (! Polyline(hdc, dPoints, (int)mapPoly->nPoints)) { DeleteObject(SelectObject(hdc, hBrush)); DeleteObject(SelectObject(hdc, hPen)); free(dPoints); MBPrintf("MapPlot", "Polygon overflow: %d points", mapPoly->nPoints); return FALSE; } DeleteObject(SelectObject(hdc, hBrush)); DeleteObject(SelectObject(hdc, hPen)); free(dPoints); } ShowStatus(v->hwndStatus, 0, "Done"); DeleteObject(SelectObject(hdc, hRgn)); return TRUE; } void DrawMap2(VARS *v, HDC hdc) { WDBII_MAP *wdbIIMap; BOOL clear = TRUE; if (v->wdbIIMode) { for (wdbIIMap = v->wdbIIMaps; wdbIIMap; wdbIIMap = wdbIIMap->next) { DrawWDBIIMap(v, hdc, wdbIIMap->name, clear); clear = FALSE; } } else DrawMap(v, hdc); } LRESULT CALLBACK EditProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static VARS *v = NULL; static WNDPROC oldProc = NULL; char s[80]; int i; static int shift = FALSE; if (! v) v = (VARS *)GetWindowLong(GetParent(hWnd), 0); if (! oldProc) oldProc = (WNDPROC)GetWindowLong(hWnd, GWL_USERDATA); switch(msg) { case WM_SETFOCUS: v->oldFocus = hWnd; break; case WM_KEYDOWN: switch (wParam) { case VK_RETURN: GetWindowText(v->hwndEdit[0], s, 80); v->origLon = atof(s); GetWindowText(v->hwndEdit[1], s, 80); v->origLat = atof(s); GetWindowText(v->hwndEdit[2], s, 80); v->zoom = atof(s); InvalidateRect(v->hwndMain, NULL, FALSE); UpdateWindow(v->hwndMain); return 0; case VK_TAB: for (i = 0; i < 3; i++) { if (GetFocus() == v->hwndEdit[i]) break; } if (! shift) i = (i == 2) ? 0: i + 1; else i = (i == 0) ? 2: i - 1; SetFocus(v->hwndEdit[i]); return 0; case VK_SHIFT: shift = TRUE; return 0; } break; case WM_KEYUP: switch (wParam) { case VK_SHIFT: shift = FALSE; return 0; } break; } return CallWindowProc(oldProc, hWnd, msg, wParam, lParam); } LRESULT CALLBACK MainWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) { static VARS *v; HDC hdc; PAINTSTRUCT ps; RECT rect; int i, offs = 5; BOOL r; HFONT hfnt; WNDPROC oldProc; static CHOOSECOLOR cc ; static COLORREF crCustColors[16]; char tmp[80]; char *title[3] = {"Lon", "Lat", "Zoom"}; DWORD id; switch (msg) { case WM_CREATE: v = (VARS *)(((LPCREATESTRUCT)lParam)->lpCreateParams); SetWindowLong(hwnd, 0, (LONG)v); v->hwndStatus = CreateStatusWnd(v->hInst, hwnd, 2); GetWindowRect(v->hwndStatus, &rect); v->statusHeight = rect.bottom - rect.top; hfnt = GetStockObject(ANSI_VAR_FONT); for (i = 0; i < 3; i++) { v->hwndLabel[i] = CreateWindowEx( 0L, "STATIC", title[i], WS_CHILD | WS_VISIBLE | SS_RIGHT, 0, 0, 0, 0, hwnd, NULL, v->hInst, NULL); SendMessage(v->hwndLabel[i], WM_SETFONT, (WPARAM)hfnt, MAKELPARAM(1, 0)); v->hwndEdit[i] = CreateWindowEx( WS_EX_CLIENTEDGE, "EDIT", (LPCTSTR)NULL, WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL, 0, 0, 0, 0, hwnd, NULL, v->hInst, NULL); oldProc = (WNDPROC)GetWindowLong(v->hwndEdit[i], GWL_WNDPROC); SetWindowLong(v->hwndEdit[i], GWL_WNDPROC, (LONG)EditProc); SetWindowLong(v->hwndEdit[i], GWL_USERDATA, (LONG)oldProc); SendMessage(v->hwndEdit[i], WM_SETFONT, (WPARAM)hfnt, MAKELPARAM(1, 0)); } sprintf(tmp, "%.1f", v->origLon); SetWindowText(v->hwndEdit[0], tmp); sprintf(tmp, "%.1f", v->origLat); SetWindowText(v->hwndEdit[1], tmp); sprintf(tmp, "%.1f", v->zoom); SetWindowText(v->hwndEdit[2], tmp); SetFocus(v->hwndEdit[0]); FileInitialize(hwnd); return 0; case WM_SIZE: SendMessage(v->hwndStatus, WM_SIZE, wParam, lParam); SetStatusParts(v->hwndStatus, 2); GetClientRect(hwnd, &rect); for (i = 0; i < 3; i++) { MoveWindow(v->hwndLabel[i], offs, rect.bottom - v->statusHeight - 32 + 3, 40, 24, TRUE); MoveWindow(v->hwndEdit[i], offs + 50, rect.bottom - v->statusHeight - 32, 50, 24, TRUE); offs += 130; } return 0; case WM_COMMAND: id = LOWORD(wParam); switch (id) { case IDM_OPEN_WDB 16b1 : AddWDBIIMap(v); return 0; case IDM_EXIT: PostQuitMessage(0); return 0; case IDM_RESET: if (! v->wdbIIMaps) return 0; DeleteWDBIIMaps(v); InvalidateRect(v->hwndMain, NULL, FALSE); UpdateWindow(v->hwndMain); return 0; case IDM_SHW_COAST: case IDM_SHW_COUNTRY: case IDM_SHW_STATE: case IDM_SHW_ISLAND: case IDM_SHW_LAKE: case IDM_SHW_RIVER: if (GetMenuState(v->hMenu, id, MF_BYCOMMAND) & MF_CHECKED) { CheckMenuItem(v->hMenu, id, MF_UNCHECKED); v->shwFeatures &= ~(id - 200); } else { CheckMenuItem(v->hMenu, id, MF_CHECKED); v->shwFeatures |= (id - 200); } InvalidateRect(v->hwndMain, NULL, FALSE); UpdateWindow(v->hwndMain); return 0; case IDM_CLR_BKGRND: case IDM_CLR_COAST: case IDM_CLR_COUNTRY: case IDM_CLR_STATE: case IDM_CLR_ISLAND: case IDM_CLR_LAKE: case IDM_CLR_RIVER: cc.lStructSize = sizeof (CHOOSECOLOR); cc.hwndOwner = hwnd; cc.hInstance = (HWND)v->hInst; cc.rgbResult = v->colors[id - 300]; cc.lpCustColors = crCustColors; cc.Flags = CC_RGBINIT | CC_FULLOPEN; cc.lCustData = 0; cc.lpfnHook = NULL; cc.lpTemplateName = NULL; if (ChooseColor(&cc)) { v->colors[id - 300] = cc.rgbResult; InvalidateRect(v->hwndMain, NULL, FALSE); UpdateWindow(v->hwndMain); } return 0; case IDM_CLR_RESET: memcpy(v->colors, v->defColors, sizeof(v->defColors)); InvalidateRect(v->hwndMain, NULL, FALSE); UpdateWindow(v->hwndMain); return 0; default: break; } break; case WM_PAINT: for (i = 0; i < 3; i++) { InvalidateRect(v->hwndLabel[i], NULL, TRUE); UpdateWindow(v->hwndLabel[i]); InvalidateRect(v->hwndEdit[i], NULL, TRUE); UpdateWindow(v->hwndEdit[i]); } hdc = BeginPaint(hwnd, &ps); DrawMap2(v, hdc); EndPaint(hwnd, &ps); if (! r) exit(1); return 0; case WM_ACTIVATE: if (LOWORD(wParam) != WA_INACTIVE) { if (v->oldFocus) SetFocus(v->oldFocus); } return 0; case WM_DESTROY: SavePlacement(hwnd, "Software\\MapPlot"); SetRegVal("Software\\MapPlot", "Show", (void*)&(v->shwFeatures), sizeof(v->shwFeatures)); SetRegVal("Software\\MapPlot", "Colors", (void*)v->colors, sizeof(v->colors)); SetRegVal("Software\\MapPlot", "OrigLon", (void*)&(v->origLon), sizeof(v->origLon)); SetRegVal("Software\\MapPlot", "OrigLat", (void*)&(v->origLat), sizeof(v->origLat)); SetRegVal("Software\\MapPlot", "Zoom", (void*)&(v->zoom), sizeof(v->zoom)); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, msg, wParam, lParam); } BOOL Init(HINSTANCE hInst, int nCmdShow) { WNDCLASS wc; RECT rect; int x = CW_USEDEFAULT, y = 0, w = 640, h = 480; VARS *v; v = (VARS *)malloc(sizeof(VARS)); v->hInst = hInst; v->oldFocus = NULL; v->mapData = v->prevPoly = NULL; v->wdbIIMode = FALSE; v->wdbIIMaps = NULL; v->defColors[0] = RGB(255,255,191); v->defColors[1] = RGB(32,144,32); v->defColors[2] = RGB(255,128,64); v->defColors[3] = RGB(255,0,0); v->defColors[4] = RGB(32,144,32); v->defColors[5] = RGB(128,128,255); v->defColors[6] = RGB(128,128,255); if (! ReadMaps(v)) return FALSE; if (! GetRegVal("Software\\MapPlot", "Show", (void*)&(v->shwFeatures), sizeof(v->shwFeatures))) { v->shwFeatures = SHW_COAST | SHW_ISLAND; } if (! GetRegVal("Software\\MapPlot", "Colors", (void*)v->colors, sizeof(v->colors))) { memcpy(v->colors, v->defColors, sizeof(v->defColors)); } if (! GetRegVal("Software\\MapPlot", "OrigLon", (void*)&(v->origLon), sizeof(v->origLon))) { v->origLon = 0.0; } if (! GetRegVal("Software\\MapPlot", "OrigLat", (void*)&(v->origLat), sizeof(v->origLat))) { v->origLat = 0.0; } if (! GetRegVal("Software\\MapPlot", "Zoom", (void*)&(v->zoom), sizeof(v->zoom))) { v->zoom = 1.0; } wc.style = CS_HREDRAW | CS_VREDRAW; wc.lpfnWndProc = (WNDPROC)MainWndProc; wc.cbClsExtra = 0; wc.cbWndExtra = sizeof(v); wc.hInstance = hInst; wc.hIcon = LoadIcon(hInst, "Icon"); wc.hCursor = LoadCursor(NULL, IDC_ARROW); wc.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); wc.lpszMenuName = "MainMenu"; wc.lpszClassName = "MainWndClass"; if (! RegisterClass(&wc)) return FALSE; if (GetPlacement("Software\\MapPlot", &rect)) { x = rect.left; y = rect.top; w = rect.right - rect.left; h = rect.bottom - rect.top; } v->hwndMain = CreateWindow( "MainWndClass", "MapPlot", WS_OVERLAPPEDWINDOW, x, y, w, h, NULL, NULL, v->hInst, (LPVOID)v); v->hMenu = GetMenu(v->hwndMain); if (v->shwFeatures & SHW_COAST) CheckMenuItem(v->hMenu, IDM_SHW_COAST, MF_CHECKED); if (v->shwFeatures & SHW_COUNTRY) CheckMenuItem(v->hMenu, IDM_SHW_COUNTRY, MF_CHECKED); if (v->shwFeatures & SHW_STATE) CheckMenuItem(v->hMenu, IDM_SHW_STATE, MF_CHECKED); if (v->shwFeatures & SHW_ISLAND) CheckMenuItem(v->hMenu, IDM_SHW_ISLAND, MF_CHECKED); if (v->shwFeatures & SHW_LAKE) CheckMenuItem(v->hMenu, IDM_SHW_LAKE, MF_CHECKED); if (v->shwFeatures & SHW_RIVER) CheckMenuItem(v->hMenu, IDM_SHW_RIVER, MF_CHECKED); ShowWindow(v->hwndMain, nCmdShow); UpdateWindow(v->hwndMain); return TRUE; } int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, INT nCmdShow) { MSG msg; if (! Init(hInstance, nCmdShow)) return 0; while (GetMessage (&msg, NULL, 0, 0)) { TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; } . 0