Mapas dinámicos con Google Maps y Directions APIs, con TypeScript y deploy de repositorio en Vercel
Veremos primero la descripción en detalle el proyecto basado en TypeScript y Vite .
Vite (palabra francesa que significa «rápido») es una herramienta de compilación que tiene como objetivo proporcionar una experiencia de desarrollo más rápida y sencilla para proyectos web modernos.
Para ejecutar un proyecto que utiliza Vite, necesitarás tener Vite instalado globalmente en tu sistema. Aquí anoto los pasos para instalar Vite:
Instalar Vite de forma global
Abre tu terminal y ejecuta el siguiente comando para instalar Vite globalmente utilizando npm (Node Package Manager):
npm install -g create-vite
Puedes usar yarn
en lugar de npm
si prefieres:
yarn global add create-vite
Este comando instala la herramienta create-vite
, que te permitirá crear nuevos proyectos Vite.
Crear un nuevo proyecto Vite
Después de instalar create-vite
, puedes usarlo para crear un nuevo proyecto Vite. Navega a la carpeta donde deseas crear el proyecto y ejecuta el siguiente comando:
create-vite nombre-del-proyecto
Esto creará una nueva carpeta llamada nombre-del-proyecto
con una estructura de proyecto Vite básica.
Además de JavaScript, Vite también es compatible con TypeScript. Cuando eliges utilizar TypeScript, asegúrate de tener TypeScript instalado globalmente:
npm install -g typescript
o con yarn
:
yarn global add typescript
Siguiendo estos pasos, deberías poder usar Vite y TypeScript, y ejecutar tu proyecto sin problemas.
A continuación, proporciono una descripción detallada de los archivos y configuraciones presentes en el proyecto:
- Estructura de Archivos:
index.html
: Este archivo es la página principal de la aplicación web. Contiene la estructura HTML básica y enlaza los estilos, scripts y la API de Google Maps. También tiene un formulario para seleccionar puntos de partida, waypoints y destino.style.css
: Este archivo contiene estilos CSS que se aplican a la página. Estos estilos pueden personalizar la apariencia de los elementos en la aplicación.index.ts
: Este es el archivo principal de TypeScript que contiene la lógica de tu aplicación. Aquí, se ha definido la funcióninitMap
que inicializa el mapa y configura el servicio de direcciones (Directions API). También implementa la funcióncalculateAndDisplayRoute
para calcular y mostrar las rutas en el mapa.vite.config.js
: Este archivo de configuración de Vite define la configuración específica del proyecto. En este caso, se ha ajustado el puerto del servidor en función de ciertos entornos.tsconfig.json
: Este archivo de configuración de TypeScript especifica las opciones de compilación para el proyecto. Define el módulo, el destino, las opciones estrictas y otras configuraciones relevantes.package.json
: Este archivo de configuración de npm contiene información sobre el proyecto, las dependencias, los scripts de npm y otras configuraciones. Las dependencias clave aquí son Vite, TypeScript y las definiciones de tipos para Google Maps.
- Configuración del Proyecto:
- Vite como tu entorno de desarrollo. Vite es un marco de desarrollo rápido para Vue y React que ofrece una configuración de desarrollo eficiente y capacidades de desarrollo rápido.
- Se ha integrado TypeScript en el proyecto, lo que mejora la capacidad de mantenimiento del código al proporcionar tipos estáticos.
- Se ha utilizado la API de Google Maps para mostrar mapas, calcular rutas y obtener información detallada de las rutas.
- Flujo de Trabajo de la Aplicación:
- Al cargar la página, se inicializa el mapa en el área designada (
div
con el id «map«) mediante la funcióninitMap
. - El formulario en la página permite al usuario seleccionar puntos de partida, waypoints y destinos.
- Al hacer clic en el botón «submit» en el formulario, se llama a la función
calculateAndDisplayRoute
, que utiliza el servicio de direcciones de Google Maps para calcular la ruta y la muestra en el mapa. - La información detallada de la ruta se presenta en el panel de direcciones.
- Al cargar la página, se inicializa el mapa en el área designada (
- Adicional:
- Se han proporcionado opciones para seleccionar múltiples waypoints y se han implementado mensajes detallados para cada segmento de la ruta.
- Se agrega una captura de error si no se puede ejecutar la consulta a la API de Google Maps, como problemas de api-key o similar.
<! -- index.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Mapa: Ruta detallada hacia el destino seleccionado</title>
<script src="https://polyfill.io/v3/polyfill.min.js?features=default"></script>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="./style.css" />
<script type="module" src="./index.ts"></script>
</head>
<body>
<div id="container">
<div id="map"></div>
<div id="sidebar">
<div>
<p>
<img src="https://demos.albertosaenz.com/BallenaNationalPark_CostaRica.jpg" class="img-fluid">
</p>
<p><h2>Ruta detallada hacia el destino seleccionado</h2></p>
<b>Partida:</b>
<select id="start">
<option value="Aeropuerto Juan Santamaría, Provincia de Alajuela">Aeropuerto Juan Santamaría</option>
<option value="Guanacaste (LIR ) Airport">Aeropuerto de Liberia, CRC</option>
<option value="Puntarenas, CRC">Puntarenas, CRC</option>
<option value="Limón, CRC">Limón, CRC</option>
</select>
<br />
<b>Puntos de ruta (Waypoints):</b> <br />
<i>(Ctrl+Click or Cmd+Click for multiple selection)</i> <br />
<select multiple id="waypoints">
<option value="San José, CRC">San José, CRC</option>
<option value="Heredia, CRC">Heredia, CRC</option>
<option value="Cartago, CRC">Cartago, CRC</option>
<option value="Guanacaste, CRC">Guanacaste, CRC</option>
<option value="Limón, CRC">Limón, CRC</option>
<option value="Alajuela, CRC">Alajuela, CRC</option>
<option value="Puntarenas, CRC">Puntarenas, CRC</option>
</select>
<br />
<b>Destino:</b>
<select id="end">
<option value="PARQUE NACIONAL MANUEL ANTONIO, CRC">PARQUE NACIONAL MANUEL ANTONIO, CRC</option>
<option value="PARQUE NACIONAL VOLCÁN POÁS, CRC">PARQUE NACIONAL VOLCÁN POÁS, CRC</option>
<option value="PARQUE NACIONAL VOLCÁN IRAZÚ, CRC">PARQUE NACIONAL VOLCÁN IRAZÚ, CRC</option>
<option value="PARQUE NACIONAL MARINO BALLENA, CRC">PARQUE NACIONAL MARINO BALLENA, CRC</option>
<option value="PARQUE NACIONAL TORTUGUERO, CRC">PARQUE NACIONAL TORTUGUERO, CRC</option>
<option value="PARQUE NACIONAL CORCOVADO, CRC">PARQUE NACIONAL CORCOVADO, CRC</option>
<option value="RESERVA BOSQUE NUBLOSO MONTEVERDE, CRC">RESERVA BOSQUE NUBLOSO MONTEVERDE, CRC</option>
<option value="PLAYA SÁMARA, CRC">PLAYA SÁMARA, CRC</option>
<option value="PLAYA FLAMINGO, CRC">PLAYA FLAMINGO, CRC</option>
<option value="PLAYA SANTA TERESA, CRC">PLAYA SANTA TERESA, CRC</option>
<option value="PLAYA PUNTA UVA, CRC">PLAYA PUNTA UVA, CRC</option>
<option value="ISLA TORTUGA, CRC">ISLA TORTUGA, CRC</option>
</select>
<br />
<input type="submit" id="submit" />
</div>
<div id="directions-panel"></div>
</div>
</div>
<script
src="https://maps.googleapis.com/maps/api/js?key=#####################&callback=initMap&v=weekly"
defer
></script>
</body>
</html>
Recuerda sustituir ##################### por tu api.key de Google Maps API.
/* style.css */
html,
body {
height: 100%;
margin: 0;
padding: 0;
}
#container {
height: 100%;
display: flex;
}
#sidebar {
flex-basis: 15rem;
flex-grow: 1;
padding: 1rem;
max-width: 30rem;
height: 100%;
box-sizing: border-box;
overflow: auto;
}
#map {
flex-basis: 0;
flex-grow: 4;
height: 100%;
}
#directions-panel {
margin-top: 10px;
}
/* index.ts */
function initMap(): void {
const directionsService = new google.maps.DirectionsService();
const directionsRenderer = new google.maps.DirectionsRenderer();
const map = new google.maps.Map(
document.getElementById('map') as HTMLElement,
{
zoom: 8,
center: { lat: 9.93, lng: -84.24 },
}
);
directionsRenderer.setMap(map);
(document.getElementById('submit') as HTMLElement).addEventListener(
'click',
() => {
calculateAndDisplayRoute(directionsService, directionsRenderer);
}
);
}
function calculateAndDisplayRoute(
directionsService: google.maps.DirectionsService,
directionsRenderer: google.maps.DirectionsRenderer
) {
const waypts: google.maps.DirectionsWaypoint[] = [];
const checkboxArray = document.getElementById(
'waypoints'
) as HTMLSelectElement;
for (let i = 0; i < checkboxArray.length; i++) {
if (checkboxArray.options[i].selected) {
waypts.push({
location: (checkboxArray[i] as HTMLOptionElement).value,
stopover: true,
});
}
}
directionsService
.route({
origin: (document.getElementById('start') as HTMLInputElement).value,
destination: (document.getElementById('end') as HTMLInputElement).value,
waypoints: waypts,
optimizeWaypoints: true,
travelMode: google.maps.TravelMode.DRIVING,
})
.then((response) => {
directionsRenderer.setDirections(response);
const route = response.routes[0];
const summaryPanel = document.getElementById(
'directions-panel'
) as HTMLElement;
summaryPanel.innerHTML = '';
// For each route, display summary information.
for (let i = 0; i < route.legs.length; i++) {
const routeSegment = i + 1;
summaryPanel.innerHTML +=
'<b>Route Segment: ' + routeSegment + '</b><br>';
summaryPanel.innerHTML += route.legs[i].start_address + ' to ';
summaryPanel.innerHTML += route.legs[i].end_address + '<br>';
summaryPanel.innerHTML += route.legs[i].distance!.text + '<br><br>';
}
})
.catch((e) => window.alert('Directions request failed due to ' + e));
}
declare global {
interface Window {
initMap: () => void;
}
}
window.initMap = initMap;
export {};
Para terminar de configurar el proyecto agregamos el archivo tsconfig.json:
{
"compilerOptions": {
"module": "esnext",
"target": "esnext",
"strict": true,
"noImplicitAny": false,
"lib": [
"esnext",
"es6",
"dom",
"dom.iterable"
],
"moduleResolution": "Node",
"jsx": "preserve"
}
}
Para utilizar los mapas de google y el servicio de direcciones que calcula rutas debes tener habilitadas las APIs Maps JavaScript y Directions, la api.key generada para tus proyectos y haber agregado el dominio donde utilizaras la aplicación a la sección de credenciales en Google Cloud Console.. Para una mejor comprensión de su uso te recomendamos consultar la documentación respectiva de Google Cloud.
// vite.config.js
// https://vitejs.dev/config/
import { defineConfig } from "vite";
export default defineConfig({
server: {
hmr:
process.env.CODESANDBOX_SSE || process.env.GITPOD_WORKSPACE_ID
? 443
: undefined,
},
});
y package.json:
{
"name": "directions-waypoints",
"description": "Samples for Google Maps JavaScript",
"version": "2.1.4",
"keywords": [
"google",
"javascript",
"maps",
"samples"
],
"homepage": "https://github.com/googlemaps/js-samples#readme",
"bugs": {
"url": "https://github.com/googlemaps/js-samples/issues"
},
"repository": {
"type": "git",
"url": "git+https://github.com/googlemaps/js-samples.git"
},
"files": [],
"license": "Apache-2.0",
"scripts": {
"dev": "vite",
"start": "vite",
"build": "vite build --outDir dist --base './'",
"test": "tsc --no-emit",
"preview": "vite preview"
},
"devDependencies": {
"@types/google.maps": "^3.48.7",
"typescript": "^4.6.3",
"vite": "^2.9.1"
},
"private": true
}
Corre el proyecto con el sigyuiente comando:
npm install && npm run dev
Empaquetar la Aplicación:
Una vez listo, necesitas empaquetar la aplicación para producción. Puedes hacer esto ejecutando el siguiente comando en tu proyecto:
npm run build
Este comando creará una carpeta dist
que contiene los archivos optimizados para producción que podrás subir a tu servidor mediante SSH o FTP.
Usando un repositorio de GitHub y Vercel:
Aquí te proporcionaré un conjunto de pasos generales para crear un repositorio en GitHub y hacer un deploy de tu aplicación Vite en Vercel.
1. Crear un Repositorio en GitHub:
- Ve a GitHub y asegúrate de tener una cuenta. Si no tienes una, regístrate.
- Inicia sesión en tu cuenta.
- Haz clic en el botón «New» para crear un nuevo repositorio.
- Dale un nombre a tu repositorio, proporciona una descripción opcional y selecciona la opción para inicializar el repositorio con un archivo
README
. - Haz clic en «Create repository».
2. Clonar el Repositorio en tu Máquina Local:
Abre una terminal en tu máquina y ejecuta los siguientes comandos (asegúrate de tener Git instalado):
git clone https://github.com/tu-usuario/tu-repositorio.git cd tu-repositorio
Reemplaza tu-usuario
y tu-repositorio
con tu nombre de usuario de GitHub y el nombre de tu repositorio.
3. Copiar tu Proyecto al Repositorio:
Copia todos los archivos de tu proyecto Vite (incluido el package.json
, src
, public
, etc.) al directorio de tu repositorio clonado.
4. Preparar y Subir los Cambios al Repositorio:
Ejecuta los siguientes comandos:
git add . git commit -m "Agregar código fuente de la aplicación Vite" git push origin main
Asegúrate de cambiar main
al nombre de tu rama principal si estás usando un nombre diferente.
5. Despliegue en Vercel:
- Ve a Vercel y crea una cuenta si no tienes una.
- Haz clic en «New Project» y selecciona tu repositorio de GitHub.
- Configura los ajustes según sea necesario (asegúrate de seleccionar la rama correcta).
- Haz clic en «Deploy».
Vercel iniciará automáticamente el proceso de construcción y despliegue de tu aplicación. Una vez finalizado, obtendrás una URL única para tu aplicación desplegada.
6. Actualizar el Despliegue en Vercel:
Cada vez que realices cambios en tu código y quieras actualizar tu aplicación en Vercel:
- Realiza los cambios en tu máquina local.
- Ejecuta los comandos de git (
add
,commit
,push
). - Vuelve a Vercel y observa cómo se inicia automáticamente un nuevo despliegue.
Siguiendo estos pasos, podrás mantener tu aplicación Vite en GitHub y desplegada en Vercel, permitiéndote actualizar fácilmente tu aplicación cuando sea necesario.
Ve a la URL que Vercel te ha proporcionado en el dashboard para ver la aplicación:
En resumen, el proyecto que te compartimos aquí proyecto utiliza TypeScript y Vite para crear una aplicación web que utiliza la API de Google Maps para calcular y mostrar rutas en un mapa interactivo. La estructura del código y la configuración del proyecto están bien organizadas para un desarrollo eficiente que puedes utilizar libremente para implementarlo en tus proyectos, y hacerle las modificaciones acorde a tus necesidades.