Si has llegado hasta aquí, significa que necesitar agregar un mapa en tu web Angular. La forma más sencilla para lograr tu objetivo es utilizar Google Maps con el siguiente comando:
npm install --save @ types/googlemapsPero no lo recomiendo. Su uso gratuito es limitado y Google únicamente ofrece un descuento mensual de $200 que, en caso de superarlo, deberás de abonar. Además de todo esto, para obtener la clave de la Api google os pedirá que proporcionéis información sobre vuestra cuenta bancaria o tarjeta de débito, no sea que excedáis el pago y se quede pendiente el cobro. Mi recomendación, es clara, no lo utilices y pasaté a OpenLayers
OpenLayers es una biblioteca repleta de funciones y de alto rendimiento destinado para aplicaciones basadas en entornos GIS. OpenLayers es un código abierto que utiliza datos de OpenStreetMap. A continuación os dejo un ejemplo para que podáis interactuar con el:
npm install leaflet
npm i --save-dev @types/leaflet
npm i leaflet-routing-machine
npm i --save-dev @types/leaflet-routing-machine
Y añadir en el fichero angular.json la siguiente información: {
// ...
"projects": {
"angular-leaflet-example": {
// ...
"architect": {
"build": {
// ...
"options": {
// ...
"assets": [
{
"glob": "**/*",
"input": "node_modules/leaflet/dist/images/", // you may need to change this path, according to your files structure
"output": "./assets"
},
],
"styles": [
"node_modules/leaflet/dist/leaflet.css",
"node_modules/leaflet-routing-machine/dist/leaflet-routing-machine.css",
],
// ..
},
// ...
},
// ...
}
}},
}
Una vez importado, creamos un componente con la siguiente vista: <div class="map-container">
<div class="map-frame">
<div id="map"></div>
</div>
</div>
Documento .css .map-container {
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
margin: 30px;
}
.map-frame {
border: 2px solid black;
height: 100%;
}
#map {
height: 100%;
}
Código Javascript.
import * as L from 'leaflet';
import 'leaflet-routing-machine';
import { icon, Marker } from 'leaflet';
import { Inject, Input, OnInit } from '@angular/core';
export const DEFAULT_LAT = 48.20807;
export const DEFAULT_LON = 16.37320;
export const TITULO = 'Proyecto';
const iconRetinaUrl = 'assets/marker-icon-2x.png';
const iconUrl = 'assets/marker-icon.png';
const shadowUrl = 'assets/marker-shadow.png';
export class StreetMapsEjemploComponent implements OnInit {
private map:any;
@Input() lat: number = DEFAULT_LAT;
@Input() lon: number = DEFAULT_LON;
@Input() titulo: string = TITULO ;
constructor() {
}
ngOnInit(): void {
this.initMap();
}
private initMap(): void {
//configuración del mapa
this.map = L.map('map', {
center: [this.lat, this.lon],
attributionControl: false,
zoom: 14
});
//iconos personalizados
var iconDefault = L.icon({
iconRetinaUrl,
iconUrl,
shadowUrl,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
});
L.Marker.prototype.options.icon = iconDefault;
//titulo
const tiles = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="https://1938.com.es">Web Inteligencia Artificial</a>'
});
//marca con pop up
const lon = this.lon + 0.009;
const lat = this.lat + 0.009;
const marker = L.marker([lat + 0.005, lon + 0.005]).bindPopup(this.titulo);
marker.addTo(this.map);
//marca forma de circulo
const mark = L.circleMarker([this.lat, this.lon]).addTo(this.map);
mark.addTo(this.map);
//ruta
L.Routing.control({
router: L.Routing.osrmv1({
serviceUrl: `https://router.project-osrm.org/route/v1/`
}),
showAlternatives: true,
fitSelectedRoutes: false,
show: false,
routeWhileDragging: true,
waypoints: [
L.latLng(this.lat, this.lon),
L.latLng(lat, lon)
]
}).addTo(this.map);
tiles.addTo(this.map);
}
}
Os podéis descargar el código en el siguiente repositorio: https://github.com/al118345/OpenStreetMapAngular12 y el siguiente video https://www.youtube.com/watch?v=2zYe5fSa2ZU:
En Angular Universal el objetivo consiste en crear un Server Side Rendering (SSR) para ser detectada por Google y mejorar nuestro SEO (https://1938.com.es/app-seo-angular)
En estas circunstancias la configuración cambia y se deben aplicar las siguientes implementaciones
Importante Entendemos que punto de instalación del proyecto lo has realizado. Es decir, partimos desde el punto que lo dejamos en proyecto anterior.
LeafletService
Crearemos un servicio nuevo que nos permita obtener, en el caso de ser un usuario navegador (no la araña de google) la información de la web
Comando
ng generate service service/leaflet
fichero: service/leaflet.service.ts
import { Injectable, PLATFORM_ID, Inject } from '@angular/core';
import { isPlatformBrowser } from '@angular/common';
@Injectable({
providedIn: 'root'
})
@Injectable()
export class LeafletService {
public L:any = null;
public Routing:any = null
constructor(@Inject(PLATFORM_ID) private platformId: Object) {
if (isPlatformBrowser(platformId)) {
this.L = require('leaflet');
this.Routing = require('leaflet-routing-machine');
}
}
}
A continuación modificamos el componente.ts con la siguiente información
var iconRetinaUrl = 'assets/marker-icon-2x.png';
var iconUrl = 'assets/marker-icon.png';
var shadowUrl = 'assets/marker-shadow.png';
constructor(private mapService: LeafletService) {
}
ngOnInit(): void {
if (this.mapService.L) {
this.initMap();
}
}
private initMap(): void {
var iconDefault = this.mapService.L.icon({
iconRetinaUrl,
iconUrl,
shadowUrl,
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
tooltipAnchor: [16, -28],
shadowSize: [41, 41]
});
this.mapService.L.Marker.prototype.options.icon = iconDefault;
this.map = this.mapService.L.map('map', {
center: [this.lat, this.lon],
attributionControl: false,
zoom: 14
});
const tiles = this.mapService.L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
maxZoom: 19,
attribution: '© <a href="https://1938.com.es">Web Inteligencia Artificial</a>'
});
//const marker = L.marker([this.lat, this.lon]);
//marker.addTo(this.map);
const lon = this.lon + 0.009;
const lat = this.lat + 0.009;
const marker = this.mapService.L.marker([lat + 0.005, lon + 0.005]).bindPopup(this.titulo);
marker.addTo(this.map);
const mark = this.mapService.L.circleMarker([this.lat, this.lon]).addTo(this.map);
mark.bindPopup(this.titulo);
mark.addTo(this.map);
const mark2 = this.mapService.L.circleMarker([lat, lon]).addTo(this.map);
mark2.addTo(this.map);
this.mapService.L.Routing.control({
router: this.mapService.L.Routing.osrmv1({
serviceUrl: `https://router.project-osrm.org/route/v1/`
}),
showAlternatives: true,
fitSelectedRoutes: false,
show: false,
routeWhileDragging: true,
waypoints: [
this.mapService.L.latLng(this.lat, this.lon),
this.mapService.L.latLng(lat, lon)
]
}).addTo(this.map);
tiles.addTo(this.map);
}
Eliminamos los siguientes imports: import * as L from 'leaflet';
import 'leaflet-routing-machine';
import { icon, Marker } from 'leaflet';
Añadimos el servicio import {LeafletService} from "./service/leaflet.service";
Y modificamos el fichero tsconfig.app.json con la siguiente configuración: "compilerOptions": {
"outDir": "./out-tsc/app",
"types": [ "node" ],
"typeRoots": [ "../node_modules/@types" ]
},
"angularCompilerOptions": {
"strictNullChecks": false,
},
Os podéis descargar el código en el siguiente repositorio: https://github.com/al118345/OpenStreetMap_Angular13_Universal
Si desean ampliar el conocimientos os invito que visitéis la continuación del articulo con el siguiente enlace https://1938.com.es/ejemplo-maps-multicapa. En este enlace podéis aprender a geolocalizar usuarios y utilizar mapas multicapa.