Si necesitan hacer una aplicación que incorpore mapas que no requiere necesariamente de que todo México esté al detalle en los mapas, les recomiendo el SDK de Virtual Earth. Se trata de un control pensado para web que se manipula con JavaScript. Sin embargo, con un mínimo de ingenio lo pueden utilizar en cualquier aplicación Windows Forms o WPF al hostear (sic) un web browser control en un UserControl de Windows Forms. O mejor aún, pueden tomar este código que hice ayer para esos fines y simplemente usarlo:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;
///
<summary>
/// Encapsulamiento (incompleto pero funcional del control de mapas de Virtual Earth
/// para su uso desde Windows Forms o WPF
/// (Requiere VS2005)
/// Software libre por Héctor Obregón http://msdnfan.blogspot.com
///
</summary>
namespace WindowsLiveControl
{
public
partial
class
WindowsLiveMapControl : UserControl
{
///
<summary>
/// Constructor publico.
///
</summary>
public WindowsLiveMapControl()
{
InitializeComponent();
this.webBrowser.DocumentText = "<html><head><title></title><meta http-equiv=\"Content-Type\"content=\"text/html; charset=utf-8\">" +
"<script src=\"http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js\"></script> <script> var map = null;" +
"function GetMap() { map = new VEMap('myMap'); map.LoadMap(new VELatLong(" +
m_dMapCenterLatitude.ToString() + ", " + m_dMapCenterLongitude.ToString() + "), " + m_iMapZoom.ToString() + ", '" + m_chMapStyle.ToString() + "' ," +
m_bMapFixed.ToString().ToLower() + "); } " +
"function AddPushPin( PinID, Latitude, Longitude, Title, Details, IconURL ) { var Pin = new VEPushpin( PinID, new VELatLong( Latitude, Longitude ), " +
"IconURL, Title, Details ); " +
"map.AddPushpin(Pin); }" +
"function SetCenter( Latitude, Longitude ) { map.SetCenter( new VELatLong( Latitude, Longitude )); } " +
"function RemovePushPin( ID ) { map.DeletePushpin( ID ); } " +
"function DeleteAllPushPins() { map.DeleteAllPushpins(); } " +
"function ZoomIn() { map.ZoomIn(); } " +
"function ZoomOut() { map.ZoomOut(); } " +
"function HideControl() { map.HideDashboard(); } " +
"function ShowControl() { map.ShowDashboard(); } " +
"function SetMapStyle( mapStyle ) { map.SetMapStyle( mapStyle ); } " +
"function SetMapZoom( level ) { map.SetZoomLevel( level ); } " +
"function SetBestMap( LatitudeArray, LongitudeArray, Count ) { " +
"var locs = new Array;" +
"for (i=0; i < Count; i++){" +
"var loc = new VELatLong( LatitudeArray[i], LongitudeArray[i] );" +
"locs.push( loc );" +
"}" +
"map.SetMapView( locs );" +
"} " +
"function SetBestMap2( lMin, loMin, lMax, loMax ) { " +
"var locs = new Array;" +
"var loc = new VELatLong( lMin, loMin );" +
"locs.push( loc );" +
"var loc = new VELatLong( lMax, loMax );" +
"locs.push( loc );" +
"map.SetMapView( locs );" +
"} " +
"</script> </head> <body onload=\"GetMap();\">" +
"<div id='myMap' style=\"position:relative; width:" + this.ClientSize.Width.ToString() + "px; height:" + this.ClientSize.Height.ToString() + "px;\"></div> </body></html>";
this.ClientSizeChanged += new
EventHandler(WindowsLiveMapControl_ClientSizeChanged);
webBrowser.SizeChanged += new
EventHandler(WindowsLiveMapControl_ClientSizeChanged);
}
///
<summary>
/// Para que ajuste automáticamente el tamaño del mapa al
/// cambiar el tamaño del control.
///
</summary>
///
<param name="sender"></param>
///
<param name="e"></param>
void WindowsLiveMapControl_ClientSizeChanged(object sender, EventArgs e)
{
this.webBrowser.DocumentText = "<html><head><title></title><meta http-equiv=\"Content-Type\"content=\"text/html; charset=utf-8\">" +
"<script src=\"http://dev.virtualearth.net/mapcontrol/v3/mapcontrol.js\"></script> <script> var map = null;" +
"function GetMap() { map = new VEMap('myMap'); map.LoadMap(new VELatLong(" +
m_dMapCenterLatitude.ToString() + ", " + m_dMapCenterLongitude.ToString() + "), " + m_iMapZoom.ToString() + ", '" + m_chMapStyle.ToString() + "' ," +
m_bMapFixed.ToString().ToLower() + "); } " +
"function AddPushPin( PinID, Latitude, Longitude, Title, Details, IconURL ) { var Pin = new VEPushpin( PinID, new VELatLong( Latitude, Longitude ), " +
"IconURL, Title, Details ); " +
"map.AddPushpin(Pin); }" +
"function SetCenter( Latitude, Longitude ) { map.SetCenter( new VELatLong( Latitude, Longitude )); } " +
"function RemovePushPin( ID ) { map.DeletePushpin( ID ); } " +
"function DeleteAllPushPins() { map.DeleteAllPushpins(); } " +
"function ZoomIn() { map.ZoomIn(); } " +
"function ZoomOut() { map.ZoomOut(); } " +
"function HideControl() { map.HideDashboard(); } " +
"function ShowControl() { map.ShowDashboard(); } " +
"function SetMapStyle( mapStyle ) { map.SetMapStyle( mapStyle ); } " +
"function SetMapZoom( level ) { map.SetZoomLevel( level ); } " +
"function SetBestMap( LatitudeArray, LongitudeArray, Count ) { " +
"var locs = new Array;" +
"for (i=0; i < Count; i++){" +
"var loc = new VELatLong( LatitudeArray[i], LongitudeArray[i] );" +
"locs.push( loc );" +
"}" +
"map.SetMapView( locs );" +
"} " +
"function SetBestMap2( lMin, loMin, lMax, loMax ) { " +
"var locs = new Array;" +
"var loc = new VELatLong( lMin, loMin );" +
"locs.push( loc );" +
"var loc = new VELatLong( lMax, loMax );" +
"locs.push( loc );" +
"map.SetMapView( locs );" +
"} " +
"</script> </head> <body onload=\"GetMap();\">" +
"<div id='myMap' style=\"position:relative; width:" + this.ClientSize.Width.ToString() + "px; height:" + this.ClientSize.Height.ToString() + "px;\"></div> </body></html>";
}
///
<summary>
/// Constructor con parámetros para inicializar el control.
///
</summary>
///
<param name="Latitude"></param>
///
<param name="Longitude"></param>
///
<param name="Zoom">De 1 a 19</param>
///
<param name="Style"></param>
///
<param name="Fixed"></param>
public WindowsLiveMapControl( double Latitude, double Longitude, int Zoom, MapStyle Style, bool Fixed):this()
{
m_dMapCenterLatitude = Latitude;
m_dMapCenterLongitude = Longitude;
m_iMapZoom = Zoom;
this.Style = Style;
m_bMapFixed = Fixed;
}
///
<summary>
/// Agrega un pin estándar al control
///
</summary>
///
<param name="Pin"></param>
public
void AddPushPin(PushPin Pin)
{
m_dictPins.Add(Pin.PinID, Pin);
object[] args = new
object[6];
args[0] = Pin.PinID;
args[1] = Pin.Latitude;
args[2] = Pin.Longitude;
args[3] = Pin.Title;
args[4] = Pin.Details;
args[5] = Pin.IconURL;
webBrowser.Document.InvokeScript( "AddPushPin", args );
}
///
<summary>
/// Centra el mapa.
///
</summary>
///
<param name="Latitude"></param>
///
<param name="Longitude"></param>
public
void SetCenter(double Latitude, double Longitude)
{
m_dMapCenterLatitude = Latitude;
m_dMapCenterLongitude = Longitude;
CenterMap();
}
///
<summary>
/// Centra el mapa en su última posición.
///
</summary>
public
void CenterMap()
{
object[] args = new
object[2];
args[0] = m_dMapCenterLatitude;
args[1] = m_dMapCenterLongitude;
webBrowser.Document.InvokeScript("SetCenter", args);
}
///
<summary>
/// Ajusta el mapa automáticamente
/// para que se vean todos los pushpins definidos.
///
</summary>
public
void FitBestMap()
{
double dMinLat = 90.0;
double dMinLong = 180.0;
double dMaxLat = -90.0;
double dMaxLong = -180.0;
foreach (PushPin p in m_dictPins.Values)
{
if (p.Latitude < dMinLat)
dMinLat = p.Latitude;
if (p.Latitude > dMaxLat)
dMaxLat = p.Latitude;
if (p.Longitude < dMinLong)
dMinLong = p.Longitude;
if (p.Longitude > dMaxLong)
dMaxLong = p.Longitude;
}
object[] args = new
object[4];
args[0] = dMinLat;
args[1] = dMinLong;
args[2] = dMaxLat;
args[3] = dMaxLong;
webBrowser.Document.InvokeScript("SetBestMap2", args);
}
///
<summary>
/// Quita un pushpin (Duh!)
///
</summary>
///
<param name="ID"></param>
public
void RemovePushPin(int ID)
{
PushPin pin;
if (m_dictPins.TryGetValue(ID, out pin))
{
object[] args = new
object[1];
args[0] = pin.PinID;
webBrowser.Document.InvokeScript("RemovePushPin", args);
}
}
public
void RemovePushPin(PushPin Pin)
{
RemovePushPin(Pin.PinID);
}
public
void DeleteAllPushPins()
{
m_dictPins.Clear();
webBrowser.Document.InvokeScript("DeleteAllPushPins");
}
public
void ZoomIn()
{
webBrowser.Document.InvokeScript("ZoomIn");
if (m_iMapZoom < 19)
++m_iMapZoom;
}
public
void ZoomOut()
{
webBrowser.Document.InvokeScript("ZoomOut");
if (m_iMapZoom > 1)
--m_iMapZoom;
}
public
void ShowNavigation()
{
webBrowser.Document.InvokeScript("ShowControl");
}
public
void HideNavigation()
{
webBrowser.Document.InvokeScript("HideControl");
}
private
void SetMapStyle()
{
object[] args = new
object[1];
args[0] = m_chMapStyle.ToString();
webBrowser.Document.InvokeScript("SetMapStyle", args);
}
private
void SetMapZoom()
{
object[] args = new
object[1];
args[0] = m_iMapZoom;
webBrowser.Document.InvokeScript("SetMapZoom", args);
}
private
double m_dMapCenterLatitude = 19.7;
public
double MapCenterLatitude
{
get { return m_dMapCenterLatitude; }
set { m_dMapCenterLatitude = value;
CenterMap();
}
}
private
double m_dMapCenterLongitude = -99.46;
public
double MapCenterLongitude
{
get { return m_dMapCenterLongitude; }
set { m_dMapCenterLongitude = value;
CenterMap();
}
}
private
int m_iMapZoom = 10;
public
int MapZoom
{
get { return m_iMapZoom; }
set {
m_iMapZoom = value;
SetMapZoom();
}
}
private
bool m_bMapFixed = false;
public
bool MapFixed
{
get { return m_bMapFixed; }
set { m_bMapFixed = value; }
}
public
enum
MapStyle { Aerial = 1, Hybrid, Oblique, Road }
private
char m_chMapStyle = 'r';
private
Dictionary<int, PushPin> m_dictPins = new
Dictionary<int, PushPin>();
public
MapStyle Style
{
set
{
if (value == MapStyle.Aerial)
m_chMapStyle = 'a';
if (value == MapStyle.Hybrid)
m_chMapStyle = 'h';
if (value == MapStyle.Oblique)
m_chMapStyle = 'o';
if (value == MapStyle.Road)
m_chMapStyle = 'r';
SetMapStyle();
}
get
{
if (m_chMapStyle == 'a')
return
MapStyle.Aerial;
if (m_chMapStyle == 'h')
return
MapStyle.Hybrid;
if (m_chMapStyle == 'o')
return
MapStyle.Oblique;
return
MapStyle.Road;
}
}
}
///
<summary>
/// Representa un PushPin...
///
</summary>
public
class
PushPin
{
private
int m_intPinID;
public
int PinID
{
get { return m_intPinID; }
set { m_intPinID = value; }
}
private
string m_strTitle;
public
string Title
{
get { return m_strTitle; }
set { m_strTitle = value; }
}
private
string m_strDetails;
public
string Details
{
get { return m_strDetails; }
set { m_strDetails = value; }
}
private
double m_dLatitude;
public
double Latitude
{
get { return m_dLatitude; }
set { m_dLatitude = value; }
}
private
double m_dLongitude;
public
double Longitude
{
get { return m_dLongitude; }
set { m_dLongitude = value; }
}
private
string m_strIconURL;
public
string IconURL
{
get { return m_strIconURL; }
set { m_strIconURL = value; }
}
public PushPin( int ID, double Latitude, double Longitude)
{
m_intPinID = ID;
m_dLatitude = Latitude;
m_dLongitude = Longitude;
}
public PushPin(int ID, double Latitude, double Longitude, string Title)
{
m_intPinID = ID;
m_dLatitude = Latitude;
m_dLongitude = Longitude;
m_strTitle = Title;
}
public PushPin(int ID, double Latitude, double Longitude, string Title, string Details)
{
m_intPinID = ID;
m_dLatitude = Latitude;
m_dLongitude = Longitude;
m_strTitle = Title;
m_strDetails = Details;
}
public PushPin(int ID, double Latitude, double Longitude, string Title, string Details, string IconURL)
{
m_intPinID = ID;
m_dLatitude = Latitude;
m_dLongitude = Longitude;
m_strTitle = Title;
m_strDetails = Details;
m_strIconURL = IconURL;
}
}
}
Y este el archivo generado por el diseñador de Windows Forms…
namespace WindowsLiveControl
{
partial
class
WindowsLiveMapControl
{
///
<summary>
/// Required designer variable.
///
</summary>
private System.ComponentModel.IContainer components = null;
///
<summary>
/// Clean up any resources being used.
///
</summary>
///
<param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected
override
void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
///
<summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
///
</summary>
private
void InitializeComponent()
{
this.webBrowser = new System.Windows.Forms.WebBrowser();
this.SuspendLayout();
//
// webBrowser
//
this.webBrowser.Dock = System.Windows.Forms.DockStyle.Fill;
this.webBrowser.Location = new System.Drawing.Point(0, 0);
this.webBrowser.MinimumSize = new System.Drawing.Size(20, 20);
this.webBrowser.Name = "webBrowser";
this.webBrowser.Size = new System.Drawing.Size(655, 484);
this.webBrowser.TabIndex = 0;
//
// WindowsLiveMapControl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.Controls.Add(this.webBrowser);
this.Name = "WindowsLiveMapControl";
this.Size = new System.Drawing.Size(655, 484);
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.WebBrowser webBrowser;
}
}
Por si lo quieren usar en XAML hay que agregar la referencia al control de Windows Forms en su proyecto WPF y luego agregar esto en la definición inicial de namespaces de su archivo….
xmlns:wfmap="clr-namespace:WindowsLiveControl;assembly=WindowsLiveControl"
y luego incluirlo así donde quieran…
<WindowsFormsHost
Name="mapHost">
<wfmap:WindowsLiveMapControl
Name="mapControl"/>
</WindowsFormsHost>
Una solución fácil para incorporar mapas simples en sus aplicaciones. Hasta la próxima…..