/*
* MapPlot
*
* Simple map drawing program for MWDB-II/WDB-II data
*
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <io.h>
#include <math.h>
#include <winlib/winlib.h>
#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:
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;
}