Click here to Skip to main content
14,693,821 members
Please Sign up or sign in to vote.
3.00/5 (2 votes)
See more:
Hello, respected professionals from CodeProject.

I need to create a dialog box that displays a map of my city.

Dialog box should have buttons for zoom in, and zoom out.

An example of what I need is closely illustrated here:
https://maps.google.com/

I just need to “paste” a map on dialogs background, and scale it properly, depending on users choice ( whether user zooms out or in, or dialog box is maximized ).

As for the city’s map image, I can get what I need from software called ArcGis, and I can export picture as bitmap, pgn, svg or something else.

I have tried exporting map image as bmp, and have used GDI to draw it as dialogs background, but quality of graphics was bad since I have used device dependent bitmaps, and since bmp files use lossy data compression.

To clarify my question:

How do you draw a geographical map on dialog’s background, scale/zoom it properly, using pure Win32 API ?

What file format should I use for map? bmp, png or svg ?

Can it be done with GDI or I need DirectDraw/ GDI+ or something else?

I can not use libraries, since I have financial issues, and I would prefer to do it myself ( if there is a free library that can help I will consider using it ).

I know that the question is broad, that is why I ask for pointers, so I can start.

Then, I will ask new questions as concrete problems occur.

I work on Windows XP, using C++ and pure Win32 API.

Thank you.

Regards.
Posted
Updated 28-Aug-13 17:18pm
v2

It's a rather lengthy question and more particularly, answer.
I'm tired right now and will explain the best I can. Apologies for any lack of quality of response.

Firstly, BMP files actually use lossless compression, so they are suitable (and the easiest to deal with. PNG files can be loaded with GDI+, but that's probably best left as an improvement to an already functioning application. The main advantage with PNGs being their size on disk.

Next, you can easily use plain ol' GDI for this task. No need for anything more heavy-weight, unless loading an image file not supported by GDI (read: unless using almost any image type - BMP being a notable exception).

You can use StretchBlt to do the scaling/drawing.
Though you will need to calculate:
(a) the portion of the image you'd like to display
(b) the aspect ratio and the output dimensions. (think letter-box display for 16:9 content on a 4:3 tv, or black side-bars if showing 4:3 content on a 16:9 display) - You need to center the image in one axis, if not both (when zoomed out a long way)


Here's some code from an old project I have here. The first function requires that GDIplus has already been initialized. While the second doesn't maintain the correct aspect ratio - it just scales the image to fit the chosen window. You'd need to change that.

// BMP, GIF, JPEG, PNG, TIFF, Exif, WMF, and EMF
HBITMAP mLoadImg(WCHAR *szFilename)
{
    HBITMAP result=NULL;

    Gdiplus::Bitmap* bitmap = new Gdiplus::Bitmap(szFilename,false);
    bitmap->GetHBITMAP(NULL, &result);
    delete bitmap;
    return result;
}

void displayImage(HWND dest, HBITMAP bmp)
{
    RECT myRect;
    BITMAP bm;
    HDC screenDC, memDC;
    HBITMAP oldBmp;

    screenDC = GetDC(dest);
    memDC = CreateCompatibleDC(screenDC);

    oldBmp = (HBITMAP)SelectObject(memDC, bmp);
    GetObject(bmp, sizeof(bm), &bm);
    GetClientRect(dest, &myRect);

    StretchBlt(screenDC, 0,0,myRect.right,myRect.bottom, memDC, 0,0,bm.bmWidth,bm.bmHeight, SRCCOPY);

    SelectObject(memDC, oldBmp);
    ReleaseDC(dest, screenDC);
    DeleteDC(memDC);
}


I generally init GDI+ in main(), like this:
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
    Gdiplus::GdiplusStartupInput gdiplusStartupInput;
    ULONG_PTR gdiplusToken;
    Gdiplus::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

    hInst = hInstance;
    InitCommonControls();
    // The user interface is a modal dialog box
    DialogBox(hInstance, MAKEINTRESOURCE(DLG_MAIN), NULL, (DLGPROC)DialogProc);
    Gdiplus::GdiplusShutdown(gdiplusToken);
}
   
v2
Comments
AlwaysLearningNewStuff 28-Aug-13 23:50pm
   
Thank you so much!
This is at least a start!
I have tried searching on Internet under "Google map win32" and found nothing...
Now I have something to work with.
God bless you!
AlwaysLearningNewStuff 29-Aug-13 18:08pm
   
This is good enough for starting point, I will post new questions as I run along problems.Thank you, +5 from me.

Regards.
enhzflep 29-Aug-13 18:17pm
   
You're welcome. Perhaps a better search would be "win32 c/c++ bitmap scaling"

Which is what the maps application does, which is what you want to do. The 'google' seems likely to me to make the search subject too specific and not likely to divulge any implementation details. I swear there's an art to this search caper - I just forget that it's one that been honed over the years. That's until I try to explain the rationale behind certain search terms, or how I would approach a search for an arbitrary subject to someone else..
Have fun with the project!
If you want to zoom in, then you neeed a very high resolution image. Since loading such an image can be very slow, you might need to have images at differnt resolution (like in Google Maps) and select appropriate tiles to display depending on the zoom factor.

You should probably used device independent bitmaps to ensure that the image are correctly displayed. Anyway, it should be easy to figure out if you program have a problem if the image is properly display in other applications.
   
Comments
AlwaysLearningNewStuff 29-Aug-13 0:22am
   
Can you give me some links to tutorials/articles or code examples?
This is my first time, and could use all the help I can get.
Thank you.
Philippe Mori 29-Aug-13 8:35am
   
By using pure Win32 Library and without any Library, you are doing all the hard work yourself.

As you have figure it out, this is a broad question and its hard to tell where to begin as there are a lot of things to learn and to do. The first thing is to figure out the image size you need at the required zoom level. If the image is really big and take to much time to be displayed using Windows image viewer or Paint, then you'll have to generate multiple images at different resolution. Usually in program like Google Maps, titles are used and there are tile for all power of 2 (almost 20 levels for the whole earth). If you application support fractional zoom, then you can stretch images which are just bigger than required ones.

Then you will have to figure out a naming scheme for all images files so that you can select the appropriate image to display according to the zoom level. Using titles of 256x256 or 512x512 would usually make sense.

As mentionned by enhzflep, BMP are uncompressed and quite large but are easier to handle particulary at the API level.
AlwaysLearningNewStuff 29-Aug-13 15:22pm
   
Thank you.
I guess I have enormous amount of work to do...
AlwaysLearningNewStuff 29-Aug-13 18:08pm
   
This is good enough for starting point, I will post new questions as I run along problems.Thank you, +5 from me. Regards.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900