Wednesday, December 3, 2008

Map Control First Look

Last night, I got to wondering how difficult it would be to slap together a map control for my phone. The goal? To host up some NLT Landsat 7 tiles from my PC and be able to browse them seamlessly from my phone, using the stylus. The Platform is my TMobile Wing, with Windows Mobile 6 Pro running CE OS 5.2. My language of choice is C# and using the Windows Mobile 6 SDK within Visual Studio 2005.

My first goal was to load up a reasonably high-res blue marble image (1024x512) and hack out some code to handle the mouse events. I soon after started tinkering a bit with the panning of the image to see what type of behavior I would receive from using managed code on the platform. Along the way, I started to get some ideas for how I could have the UI behave in the longer term. I started asking myself some reasonably simple questions, such as:

.. should the app run full screen or not?
.... are the standard menu buttons at the bottom of the screen necessary?
...... what should my mouse clicks Do?
........ with respects to mouse clicks, what is the nicest way to zoom?

I was able to work out a small demo, nothing spectacular but i'll probably spend some time building off of it this week. I will probably spend a bit of time tomorrow night working on the network code, request buffering, etc... For now, enjoy this small demo of how it currently acts.



Some things to take note of:

- The behavior when sporadically panning the image is pretty good
- You can see some artifact along the outskirts of the image, although you'd never see this once the outskirt data is being buffered in
- There's an annoying "jump" glitch, which I will clean up tomorrow :-)

2 comments:

end.13.ss said...

Nice work! I just use the same way for embeding google earth into a WPF window, but I am wondering how to add controls like button and let them render over google earth. Could you please drop some ideas?

mav007100 said...

hi joe, thanks a lot for this project. i m trying to get specific lat and long location by the code below, but i m not getting result. please post me an example if you are free and not busy. i will be very glad and thankful to you.

my email: zeshan_hyder@hotmail.com

code:
=====

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Diagnostics;


using EARTHLib;

namespace resize_google_earth
{

public partial class Form1 : Form
{


[DllImport("user32.dll")]
private static extern int SetParent(
int hWndChild,
int hWndParent);

[DllImport("user32.dll")]
private static extern bool ShowWindowAsync(
int hWnd,
int nCmdShow);

[DllImport("user32.dll", SetLastError = true)]
private static extern bool PostMessage(
int hWnd,
uint Msg,
int wParam,
int lParam);

[DllImport("user32.dll", EntryPoint = "SetWindowPos")]
private static extern bool SetWindowPos(
int hWnd,
int hWndInsertAfter,
int X,
int Y,
int cx,
int cy,
uint uFlags);

[DllImport("user32.dll")]
private static extern int SendMessage(
int hWnd,
uint Msg,
int wParam,
int lParam);

private const int HWND_TOP = 0x0;
private const int WM_COMMAND = 0x0112;
private const int WM_QT_PAINT = 0xC2DC;
private const int WM_PAINT = 0x000F;
private const int WM_SIZE = 0x0005;
private const int SWP_FRAMECHANGED = 0x0020;

public Form1()
{


ge = new ApplicationGEClass();

ShowWindowAsync(ge.GetMainHwnd(), 0);
SetParent(ge.GetRenderHwnd(), this.Handle.ToInt32());
ResizeGoogleControl();

double lat = 44.39165;
double lon = 4.71157;
double alt = 1000;
AltitudeModeGE AltiGe = AltitudeModeGE.AbsoluteAltitudeGE;
double range = 100;
double tilt = 0;
double azimuth = 0;
double speed = 5;

ge.SetCameraParams(lat, lon, alt, AltiGe, range, tilt, azimuth, speed);

}

private void Form1_Resize(object sender, EventArgs e)
{
ResizeGoogleControl();
}

private void ResizeGoogleControl()
{
SendMessage(ge.GetMainHwnd(), WM_COMMAND, WM_PAINT, 0);
PostMessage(ge.GetMainHwnd(), WM_QT_PAINT, 0, 0);

SetWindowPos(
ge.GetMainHwnd(),
HWND_TOP,
0,
0,
(int)this.Width,
(int)this.Height,
SWP_FRAMECHANGED);

SendMessage(ge.GetRenderHwnd(), WM_COMMAND, WM_SIZE, 0);
}



private EARTHLib.ApplicationGE ge = null;



private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
// Attach to the running Google Earth process and close it
foreach (Process thisProcess
in Process.GetProcessesByName("googleearth"))
{
if (!thisProcess.CloseMainWindow())
thisProcess.Kill();
}
}


}
}