Este es un artículo escrito por Calvin Allen. Calvin es un desarrollador .NET en Columbus, OH que disfruta diseñando software que no sólo resuelve problemas de negocio, sino que es fácil de usar, dentro del presupuesto y a tiempo. Si no está diseñando software, está aprendiendo cómo ser un mejor desarrollador de software. Esto no es sólo una carrera para él - es también un estilo de vida.
Sigue el post de Calvin en consultar el código fuente y GitHub y descargando la última versión preliminar para desarrolladores de Couchbase.
¿Qué es GeoJSON? GeoJSON.org lo define como:
"GeoJSON es un formato para codificar una variedad de estructuras de datos geográficos"
Pero, ¿qué significa realmente? Básicamente, se trata de un formato estándar que utiliza la estructura JSON para definir objetos geográficos. Estos "objetos geográficos" pueden ser varios, desde un simple "punto" hasta un objeto más complejo, como un "polígono".
He aquí un sencillo ejemplo de "punto en el mapa" para las "Islas Dinagat":
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{ "tipo": "Colección de características", "características": [ { "tipo": "Característica", "geometría": { "tipo": "Punto", "coordenadas": [ 125.6, 10.1 ] }, "propiedades": { } } ] } |
Ahora que ya conoces todos los antecedentes, te estarás preguntando: "¿Por qué necesito GeoJSON?". La respuesta sencilla es que se trata de un estándar actualmente admitido en diversas tecnologías cartográficas, como Google Maps. Con tus datos ya en formato GeoJSON, puedes proporcionar esos datos directamente a Google Maps, y renderiza tu objeto como se describe. No sólo te ahorra tener que "rodar tu propio" formato, sino que otros proveedores ya lo soportan, lo que puedes aprovechar como desees.
Manos a la obra.
Voy a demostrar el formato GeoJSON utilizando una aplicación .NET MVC, Couchbase (Community) Server (y el SDK .NET), y Google Maps - voy a tener que asumir que tienes algún conocimiento práctico de todas estas utilidades.
No voy a entrar en detalles sobre cómo crear el proyecto MVC, o la instalación / configuración de Couchbase, ya que hay un montón de otros tutoriales / artículos por ahí que describen cómo lograr estos elementos, especialmente en Matthew Groves Blog de Couchbase.
Una cosa que mencionaré ahora, es que he llamado al bucket de Couchbase "features", y lo he precargado (todo a través de la Consola de Couchbase) con dos documentos - uno para un polígono alrededor de Roma, y otro con un punto sobre las Islas Dinagat (como se ve arriba). Ambos archivos json se pueden encontrar en el repositorio de github al que enlazaré más adelante en el artículo.
Con el nuevo sitio web MVC cargado en Visual Studio, abre la consola del gestor de paquetes NuGet y escribe el siguiente comando para cargar el SDK .NET de Couchbase:
1 |
Instale-Paquete couchbasenetclient |
Una vez que el SDK .NET de Couchbase haya terminado de instalarse, ejecute el siguiente comando para instalar la biblioteca geojson:
1 |
Instale-Paquete geojson.red |
El primer paquete, "couchbasenetclient", se utilizará para comunicarnos con nuestro servidor local Couchbase para gestionar nuestros documentos GeoJSON. Se trata de una librería creada / soportada por el equipo de Couchbase. La siguiente, "geojson.net", es una librería de ayuda para crear / leer documentos GeoJSON. Bajo el capó, la biblioteca geojson.net utiliza JSON.Net para la serialización / deserialización json de los tipos .NET que la biblioteca nos proporciona. Podrías prescindir de este paquete/biblioteca y gestionar los tipos tú mismo, pero para simplificar las cosas, he decidido utilizarlo.
Lo primero que tenemos que hacer es cablear nuestro controlador. Voy a reutilizar el "HomeController" que ya existe en el proyecto.
En primer lugar, voy a añadir un constructor, que vamos a utilizar para almacenar nuestro cubo:
1 2 3 4 5 6 7 8 9 |
público clase InicioControlador : Controlador { privado sólo lectura IBucket _bucket; público InicioControlador() { _bucket = ClusterHelper.GetBucket("características"); } } |
Ahora, voy a necesitar tres puntos finales -
- Uno para obtener una lista de todas las características
- Uno que actuará como un simple enrutamiento a la página del mapa (verás a lo que me refiero)
- Y, por último, una a la que la API de Google Maps realizará una llamada directa para obtener el JSON de la función.
Aquí están los tres:
Primero - es la acción que devuelve la lista completa de características en mi cubo Couchbase. Se trata de una simple consulta N1QL para obtener los ID de las características como una lista de cadenas. (Sólo me importa el ID de la característica en la página de la lista)
1 2 3 4 5 6 7 8 9 10 11 12 13 |
público AcciónResultado Características() { var solicitar = Solicitud de consulta.Cree("SELECT META().id as `id` FROM `features` as f"); solicitar.Consistencia de escaneado(Consistencia de escaneado.SolicitarPlus); var featureIds = _bucket .Consulta<dinámico>(solicitar) .Filas .Seleccione(x => x.id.ToString()) .ToList(); devolver Ver(featureIds); } |
Este es el método de enrutamiento simple que utilizo mientras navego desde la página de la lista para mantener el ID de la característica solicitada en la que el usuario hizo clic.
1 2 3 4 |
público AcciónResultado MapFeature(cadena id) { ViewBag.FeatureId = id; devolver Ver(); } |
Y, por último, este método se llama a través de la API de Google Maps en la página MapFeature para obtener el JSON de la característica que el usuario desea mapear (de nuevo, utilizando el objeto FeatureCollection de la biblioteca geojson.net - esto utiliza Json.Net para serializar ese objeto, que viene con sus propios serializadores en la biblioteca también).
1 2 3 4 5 6 |
público ContenidoResultado GetFeatureJson(cadena id) { var función = _bucket.Visite<FeatureCollection>(id).Valor; var json = JsonConvert.SerializarObjeto(función); devolver Contenido(json, "application/json"); } |
Pasemos ahora a las páginas de visualización propiamente dichas (sólo hay dos)
En la página "Características", que no es más que un listado de las características de nuestro bucket de Couchbase, simplemente mostramos cada uno de los ID de las características en un enlace de acción dentro de una lista desordenada:
1 2 3 4 5 6 7 8 9 |
@modelo Lista<cadena> <h2>Características</h2> <ul> @foreach (var función en Modelo) { <li>@Html.ActionLink(función, "MapFeature", "Inicio", nuevo { id = función }, null)</li> } </ul> |
La última página, MapFeature, es la que hace el "trabajo pesado":
1 2 3 4 5 6 |
<h2>Mapa Característica</h2> @{ var id = ViewBag.FeatureId; } |
$(function () {
var map = new google.maps.Map(document.getElementById('map'), {
zoom: 6
});
map.data.loadGeoJson('/Home/GetFeatureJson/@id');
//la llamada de retorno para cada una de las características en el bucle - la última gana
function forEachGeometry(feature) {
feature.getGeometry().forEachLatLng(resetCenter);
};
//toma la Latituta y la Longitud de cada Geometría y restablece el punto central en el mapa - el último gana - totalmente ineficiente
function resetCenter(latLng) {
map.setCenter(latLng);
};
//cada vez que se añada una característica al mapa, repasa la colección - completamente ineficiente, pero debería proporcionar una idea
map.data.addListener('addfeature', function (e) {
map.data.forEach(forEachGeometry);
});
});