Realizar búsquedas con Virtual Earth

Febrero de 2007

Publicado: 26 de marzo de 2007

La búsqueda basada en mapas requiere un mapa y la capacidad de buscar ubicaciones importantes. Afortunadamente, Virtual Earth Map Control nos ofrece las dos piezas necesarias. Lo mejor es que podemos crear un sistema de búsqueda basado en mapas con tan solo HTML, JavaScript y un poco de CSS.

El control VEMap no sólo muestra el mapa sino que también proporciona cuatro métodos distintos para realizar una búsqueda:

  • El control What/Where disponible en local.live.com también está disponible en el control básico VEMap. Es posible activar este control con una línea adicional de código JavaScript.

  • El método FindLocation() realiza la búsqueda de una ubicación. Si se encuentra una ubicación coincidente, el mapa automáticamente se volverá a centrar en la ubicación y se acercará a un nivel apropiado.

  • El método FindNearby() realiza una búsqueda "what" para encontrar negocios cercanos al centro actual del mapa. Esta búsqueda usa la misma base de datos de las páginas amarillas que local.live.com.

  • El método Find() ofrece el mayor control sobre la búsqueda, ya que se puede especificar tanto lo que se busca como dónde se busca. También es posible recibir los resultados de la búsqueda en una función de devolución de llamada JavaScript.

Mediante la elección de un método Find apropiado, se puede crear una aplicación de búsqueda totalmente funcional basada en mapas.

En esta página

Introducción Introducción
El control What/Where El control What/Where
El método FindLocation El método FindLocation
El Método FindNearby El Método FindNearby
El poder total de la búsqueda El poder total de la búsqueda
Trabajo con los resultados Trabajo con los resultados
Configuración de la vista de resultados Configuración de la vista de resultados
Modificación del método DoFind Modificación del método DoFind
El método ProcessResults El método ProcessResults
Conclusión Conclusión

Introducción

Antes de emplear las diversas opciones para encontrar ubicaciones, es preferible empezar con un mapa básico de Virtual Earth:

<html>
<head>
<script src="http://dev.virtualearth.net/mapcontrol/v4/mapcontrol.js"></script>
<script>
  var map;
  function OnPageLoad()
  {
    map = new VEMap('myMap');
    map.LoadMap();
  }
</script>
<body onload="OnPageLoad();">
    <div id="myMap" style="position:relative;width:600px;height:400px;"></div>
</body>
</html>

Listado 1 Página básica (Find.html)

Si carga esta página en un explorador, debe consultar un mapa de los Estados Unidos con el panel básico de navegación de Virtual Earth.

El control What/Where

La forma más fácil de aprovechar la funcionalidad de búsqueda es sencillamente activando el control What/Where. Agregue la línea siguiente de código al final del método OnPageLoad():

map.ShowFindControl();

Listado 2 Activación del control Find

Si carga la página revisada en el explorador, el control What/Where aparecerá en la esquina superior derecha:

Figura 1 El control What/Where

Si escribe una dirección dentro del cuadro "Where" (por ejemplo, Denver) y hace clic en "Find", el mapa se volverá automáticamente a centrar en su ubicación. Si Virtual Earth no puede encontrar una coincidencia exacta, verá el elemento emergente para solucionar ambigüedades:

Figura 2 Diálogo para solucionar ambigüedades

Basta con hacer clic en la ubicación deseada y el mapa se volverá a centrar y se ampliará al nivel apropiado:

Figura 3 El mapa se vuelve a centrar

Si los usuarios escribieron información en el cuadro What, veremos un conjunto de chinchetas que coinciden con la búsqueda en las páginas amarillas de la información entrada. Por ejemplo, podemos buscar "coffee" en "Vail, Colorado":

Figura 4 What y Where

Por supuesto, existen algunos inconvenientes con el control What/Where. Primero, el control es demasiado amplio. El mapa tendría que tener por lo menos 635 píxeles de ancho para mostrar el control completo en el mapa. Podemos ajustar el estilo encontrando las entradas de CSS pertinentes, pero esa funcionalidad no es fácil de exponer y no se admite directamente. Un segundo problema es que la búsqueda está más bien toscamente definida. Es decir, el usuario puede escribir una dirección en cualquier formato y Virtual Earth hará la mejor estimación posible. Es posible solucionar ambas limitaciones creando nuestro propio control de búsqueda.

El método FindLocation

El método FindLocation() es muy sencillo y fácil de usar. Todo lo que se debe hacer es pasar una cadena que contenga la dirección. En este ejemplo, queremos forzar a nuestros usuarios a escribir un código postal. Por lo tanto, crearemos un panel que contenga un cuadro de texto y un botón de búsqueda. Vincularemos también el botón de búsqueda a nuestro método FindLocation.

En primer lugar, necesitamos algo más de HTML. Agregue la siguiente etiqueta div al cuerpo del archivo html:

<div id="SearchPanel" >
  <table border=0>
  <tr><td bgcolor='#C0C0CF'><p align='center'>Search</p></td></tr>
  <tr><td><p align='center'>
    Zip Code:
    <INPUT id="txtZip" type="text" value="" name="txtZip">
  </td></tr>
  <tr><td bgcolor='#E0E0E0'><p align='center'>
    <input type="button" value="Search" onclick="DoFind();" id="Search" 
name="Search" />
  </td></tr>
  <table>
</div>

Listado 3 Adición del panel

A continuación, necesitamos agregar alguna información de estilo para que nuestro control de búsqueda tenga mejor aspecto. Agregue el siguiente bloque de secuencias de comandos al encabezado de su página:

style type="text/css" media="screen">
  #SearchPanel
  {
    width: 150px;
    border-style: solid;
    border-width: 1px;
    border-color: lightgray;
    background: white;
  }
</style>

Listado 4 Mejora del estilo del cuadro Find

Ahora, necesitamos asociar nuestro panel al mapa y colocarlo en la posición deseada. Reemplace el método OnPageLoad () por lo siguiente:

function OnPageLoad()
{
  map = new VEMap('myMap');
  map.LoadMap();

  var search = document.getElementById('SearchPanel');
  map.AddControl(search);
  search.style.left = "475px";
  search.style.top = "5px";
}

Listado 5 Asociación del panel de búsqueda

Finalmente, debemos crear nuestro propio método DoFind(). Agregue lo siguiente al bloque de secuencias de comandos:

function DoFind()
{
  map.FindLocation(document.getElementById('txtZip').value);
}

Listado 6 Implementación de FindLocation

Si ahora cargamos la aplicación, nuestro propio cuadro de búsqueda personalizado debe aparecer en la esquina superior derecha. Escriba su código postal favorito, haga clic en el botón Find y vea que sucede:

Figura 5 FindLocation en acción

Podríamos agregar validación para garantizar que los usuarios escribieron un código postal válido, pero lo dejaremos como un ejercicio para el lector.

El Método FindNearby

<div id="SearchPanel" >
  <table border=0>
  <tr><td bgcolor='#C0C0CF'><p align='center'>Search</p></td></tr>
  <tr><td><p align='center'>
      Business:
      <INPUT id="txtBiz" type="text" value="" name="txtBiz">
  </td></tr>
  <tr><td bgcolor='#E0E0E0'><p align='center'>
    <input type="button" value="Search" onclick="DoFind();" id="Search" 
name="Search" />
  </td></tr>
  <table>
</div>

Listado 7 El cuadro de texto What

También necesitamos cambiar el método DoFind():

function DoFind()
{  map.FindNearby(document.getElementById('txtBiz').value);
}

Listado 8 Uso de FindNearby

Observe que el método FindNearby() tiene casi el mismo aspecto que el método FindLocation().

Si ahora cargamos la página en un explorador, podemos realizar una búsqueda "What" de un negocio:

Figura 6 El método FindNearby

Es posible que deba hacer zoom en un área de interés antes de ejecutar la búsqueda. La vista predeterminada del mapa mostrará completamente los Estados Unidos y realizará búsquedas cerca del punto central del mapa.

El poder total de la búsqueda

La última elección para realizar búsquedas le brinda un mayor control tanto sobre el proceso de búsqueda como sobre los resultados. Empezaremos simplemente combinando las búsquedas FindLocation y FindNearby en un solo método de búsqueda.

En primer lugar, agregue los cuadros de texto Business y Zip a su html:

<div id="SearchPanel" >
  <table border=0>
  <tr><td bgcolor='#C0C0CF'><p align='center'>Search</p></td></tr>
  <tr><td><p align='center'>
    Zip Code:
    <INPUT id="txtZip" type="text" value="" name="txtZip">
  </td></tr>
  <tr><td><p align='center'>
      Business:
      <INPUT id="txtBiz" type="text" value="" name="txtBiz">
  </td></tr>
  <tr><td bgcolor='#E0E0E0'><p align='center'>
    <input type="button" value="Search" onclick="DoFind();" id="Search" 
name="Search" />
  </td></tr>
  <table>
</div>

Listado 9 El panel de búsqueda completo

A continuación, es necesario reemplazar el método DoFind() de nuevo:

function DoFind()
{
  var where = document.getElementById('txtZip').value;
  var what = document.getElementById('txtBiz').value;

  map.Find(what, where, 1);
}

Listado 10 El método Find con What y Where

Ahora, si cargamos la página web, debemos ver los cuadros de texto What y Where

Figura 7 Búsqueda mediante Find

Nuestra aplicación es ahora totalmente equivalente a la versión inicial usada para crear el control What/Where.

Trabajo con los resultados

En lugar de mostrar los resultados automáticamente, quizás deseamos realizar algún filtrado o procesamiento adicionales. Es posible incluso que deseemos mostrar los resultados en un panel nuevo. Afortunadamente, el método Find(), a diferencia del resto de nuestras elecciones, permite definir una función de devolución de llamada JavaScript. El método de devolución de llamada se activará cuando finalice la búsqueda y ofrece acceso a los resultados.

En función del nombre que se asigne a Find(), es posible recibir dos tipos de resultados distintos:

  • Si el método Find devuelve un "Where", recibiremos un objeto VESearchResult. Cada objeto contiene un valor de identificación y un par latitud/longitud.

  • Si el método Find devuelve un "What", recibiremos un objeto VEFindResult. Cada objeto contiene varias propiedades que incluyen el nombre, la descripción, el teléfono y un par latitud/longitud.

Puesto que no sabemos con seguridad el tipo de resultado que se devolverá, necesitamos diferenciar los tipos de resultados. Un VESearchResult siempre tendrá un campo ID no nulo, mientras que un VEFindResult siempre tendrá un campo de nombre no nulo.

Configuración de la vista de resultados

Deseamos mostrar los resultados en una tabla en el extremo derecho del mapa. Necesitamos agregar algún html y css para definir la tabla. Empiece agregando la siguiente etiqueta <div> al cuerpo de la página:

<div id="SearchResults" ></div>

Listado 11 Los resultados de búsqueda con la etiqueta Div

A continuación, agregue algún CSS para definir la etiqueta div. Agregue este nuevo estilo a la sección de estilo:

#SearchResults
{
  display: none;
  width: 325px;
  border-style: solid;
  border-width: 1px;
  border-color: lightgray;
  background: white;
}

Listado 12 CSS para los resultados de búsqueda

Finalmente, deseamos asociar la etiqueta div como un control para el objeto del mapa. Volvemos a la función OnPageLoad() y agregamos algo de código nuevo al final de la función:

var results = document.getElementById('SearchResults');
map.AddControl(results);
results.style.left = "640px";
results.style.top = "5px";
map.ShowDisambiguationDialog(false);

Listado 13 Configuración de la vista de resultados de búsqueda

Observe que, al igual que con el panel What/Where, es necesario establecer la posición tras agregar el control al mapa. Desactivamos también la característica automática de solución de ambigüedades. Si omitimos esta última línea, es posible que no podamos usar nuestros resultados porque el usuario se verá forzado a decidir una ubicación después que se realiza la devolución de llamada. Al desactivar la solución de ambigüedades, se está diciendo al mapa que elija automáticamente la primera ubicación devuelta.

Modificación del método DoFind

Ahora, debemos agregar un parámetro adicional a nuestra llamada Find(). El parámetro adicional identifica el método de devolución de llamada JavaScript:

function DoFind()
{
  var where = document.getElementById('txtZip').value;
  var what = document.getElementById('txtBiz').value;
  map.Find(what, where, 1, ProcessResults);
}

Listado 14 DoFind

El método ProcessResults

Finalmente, es necesario configurar nuestro método ProcessResults(). Deseamos crear una tabla y colocarla en la etiqueta <div> de resultados de búsqueda.

function ProcessResults(findResults)
{
  var results ="<table><tr><td colspan=3 align='center'>Find results</td></tr>";
  results += "<tr><td>Name</td><td>Description</td><td style='width: 
100px;'>Phone</td></tr>";

  var numresults = 5;
  numresults = Math.min(numresults, findResults.length);

  for (r=0; r<numresults; r++)
  {
     results += "<tr><td>";
     if (findResults[r].Name!=null) //VEFindResult objects
     {

      results += findResults[r].Name + "</td><td>";
      results += findResults[r].Description + "</td><td style='width: 100px;'>";
      results += findResults[r].Phone;
     }
     else
     {
     results += "Unknown</td><td>N/A";
     }
     results += "</td></tr>";
  }
  results += "</table>";

  var resultPane = document.getElementById('SearchResults');
  resultPane.style.display = 'block';
  resultPane.innerHTML = results;
}

Listado 15 El método ProcessResults

Si ahora cargamos la página, podremos escribir un código postal y un negocio y ver los resultados:

Figura 8 La vista final

Aunque la aplicación básica funciona, siempre es posible agregar más características. Por ejemplo, se puede agregar validación para garantizar que el usuario sólo escriba un código postal. También se puede hacer que la tabla muestre más o menos resultados e incluso permitir al usuario que avance a la página del siguiente conjunto de resultados.

Conclusión

La variedad de elecciones de búsqueda integradas en el control VEMap otorga una gran flexibilidad en el diseño de búsquedas basadas en mapas. Tanto si desea realizar una búsqueda sencilla como un control complejo sobre la entrada de usuario, todo lo que necesita es JavaScript, CSS, HTML y el SDK de Virtual Earth.

Este artículo ha sido redactado por el MVP Robert McGovern (Virtual Earth/MapPoint) de Infusion Development.

Mostrar: