Diseño y distribución en plantaGestión de almacenesLocalización de instalaciones

Método de localización de instalaciones utilizando mapas de calor (Google Maps + Javascript)

Google Maps (Javascript)

Mucho se ha desarrollado en la literatura académica acerca de los métodos o algoritmos de localización de instalaciones. En el estudio de localización se pueden abordar dos grandes aspectos: macrolocalización y microlocalización. En ambos casos el procedimiento de análisis de localización abordará las fases de:

  • Análisis preliminar
  • Búsqueda de alternativas de localización
  • Evaluación de alternativas
  • Selección de localización
Macrolocalización: Es decir, la selección de la región o zona más adecuada, evaluando las regiones que preliminarmente presenten ciertos atractivos para la industria que se trate.

Microlocalización: Es decir, la selección específica del sitio o terreno que se encuentra en la región que ha sido evaluada como la más conveniente.

Algunos de los algoritmos que apoyan las fases del procedimiento de localización, presentan dificultades propias del contexto operacional real que se pretende abordar. Por ejemplo, el Método de Centro de Gravedad, requiere de la consideración de un conjunto de instalaciones existentes, y su objetivo es el de establecer la ubicación de un punto de servicio / atención / suministro para los puntos dados. Requiere para ello de la existencia de un sistema de coordenadas con un punto de origen.

Recuerdo que cuando utilicé este algoritmo en la Universidad utilizamos la copia de un mapa de la región, sobre ella trazamos un plano cartesiano, definimos las ubicaciones del caso, registramos las coordenadas y como resultado obtuvimos las coordenadas de la localización ideal. La dificultad subyace en la falta de practicidad.

Otro método, como el Heurístico de Ardalan, utiliza un conjunto de instalaciones existentes, y un conjunto de localizaciones tentativas. Toma como base una matriz de distancias y el objetivo consiste en optimizar la cobertura. Sin embargo, obtener la información requiere del levantamiento de mínimo una matriz n * m. En la medida en la que el número de ubicaciones aumenta el algoritmo se convierte en complejo.


Desde hace algunos años, la disponibilidad de servidores de aplicaciones de mapas, los sistemas de posicionamiento satelital, los sistemas de información geográfica, entre otros; han facilitado la adopción de soluciones basadas en entornos reales, como herramientas que apoyen algunas de las fases del procedimiento de localización de ubicaciones.

En este artículo utilizaremos mapas de calor y servidores de aplicaciones de mapas, como herramienta visual de soporte en los procesos de selección de localizaciones.

¿Qué es un mapa de calor?

mapa de calorEn este contexto, un mapa de calor es una capa de visualización que se utiliza para representar la intensidad de los datos en puntos geográficos (ubicaciones). Cuando la capa de mapa de calor se encuentra habilitada, aparecerá una superposición de color en la parte superior del mapa. De forma predeterminada (es un estándar), las áreas de mayor intensidad se colorearán en rojo y las áreas de menor intensidad aparecerán en verde.

La intensidad de los datos de una región en particular puede aumentar dada la concentración de ubicaciones en una zona específica. Del mismo modo, pueden utilizarse puntos de datos ponderados, es decir, que un punto geográfico en particular puede tener un peso que hará que el punto se represente con mayor intensidad.

Un ejemplo de aplicación práctica de los puntos de datos ponderados, puede ser la cantidad de individuos que vivan en un punto específico. En este caso, los puntos ponderados ayudarán a representar densidad poblacional.


Mapas de calor + Google Maps

El servidor de aplicaciones de mapas más popular del mundo: Google Maps, cuenta con una librería de visualización que nos permite el uso de mapas de calor con puntos normales o ponderados. Evaluaremos su uso por medio de un caso práctico.

El Departamento de Desarrollo Sostenible de la ciudad de Cali se encuentra implementando una estrategia piloto de recolección de aceite de cocina usado. Ha articulado este proyecto con una Universidad, la cual desarrolló 4 contenedores inteligentes (BIN’s) para la disposición del bioresiduo. En investigaciones asociadas, la Universidad ha determinado que el reciclaje del aceite es un problema de densidad; esto quiere decir que es vital la ubicación de los contenedores (cobertura), para así mismo optimizar el proceso de disposición y recolección. El proyecto piloto piensa articular a las instituciones de educación como puntos potenciales de recolección. Por medio de las instituciones piensan socializar el programa con la comunidad. El primer reto del proyecto consiste en determinar la ubicación de los contenedores inteligentes (4 unidades). La información relacionada con las instituciones de educación que hacen parte del programa (ubicación geográfica / población estudiantil), se detalla a continuación:

 

Establecimiento Latitud / Longitud Número de estudiantes
 Comfandi San Nicolás 3.4535911182,  -76.522548858 1494
 Mayor de Santiago de Cali 3.4515777580,  -76.510232156 908
 Municipal Comfandi 3.4481079145, -76.510747140 697
 Internado San Carlos 3.4469941349, -76.515253250 1714
 León de Greiff 3.4479794015, -76.499932474 1731
 Nuestra Señora de la Anunciación 3.4451521118, -76.496413416 2297
 Fernando de Aragón 3.4373556029, -76.513837044 1265
 Casa Evangélica 3.4379553366, -76.522999470 1658
 San Alberto Magno 3.4330289411, -76.527076427 604
 Santa María Goretty 3.4334144860, -76.507206624 416
 San Alberto Magno 3.4331574561,  -76.526733104 1584
 San Ignacio de Loyola 3.4317866287,  -76.517334644 2350
 Nuestro Futuro 3.4306299916, -76.503601735 964
 Sabio Caldas 3.4290878065, -76.516605083 329
 CREAD 3.4250609784, -76.514888470 774
 Licomtec 3.4166645586, -76.516733829 1818
  Nuestra Señora De La Providencia 3.4195347715,  -76.495919889 1530
 Real Suizo 3.4152080294, -76.493237680 2106
 Nuevo Edén 3.4157220988, -76.533835594 330
 Católico 3.4130660706, -76.539843742 976
 Santa María Stella 3.4270315559,  -76.551345054 1975
 Santa Isabel 3.4080535495,  -76.508172225 936
 Compartir 3.4319576632,  -76.474955752 1563
 Lancaster 3.4007708157,  -76.551774213 1219
 Parroquial Divino Salvador 3.3970865884, -76.542590328 1954
 Reyes Católicos 3.3933166668,  -76.537354656 399
 Liceo Anglo del Valle 3.3873187189,  -76.519759374 1741
 Laurence 3.3834202377, -76.520789343 1111
 Los Almendros 3.3812782083,  -76.520231443 1826
 Bautista 3.3772083395,  -76.523278432 1772
 Lacordaire 3.3781508370,  -76.544607357 1965
 General José María Córdoba 3.3935733137, -76.549328047 841
 El Hogar 3.3907458636,  -76.550315100 770
 Americano 3.3790932549, -76.546881873 650
 Santa Filomena 3.4019699352, -76.513450821 1401
 Tomás Vasconi 3.4030409276, -76.517313202 1474
 República del Salvador 3.4044546356, -76.521433075 1926
 Los Andes 3.4296010767,  -76.537612160 1566
Villacolombia 3.4454939428, -76.501692020 2354
Las Américas 3.4492208216, -76.505940638 2043
Santa Fe 3.4422382667, -76.509888850 2333
Evaristo García 3.4407817764, -76.517527780 696
Alfredo Vásquez Cobo 3.4355983661,  -76.516454898 1073
Ciudad de Cali 3.4311431813,  -76.512721263 1275
INEM 3.4827619907, -76.4997608303 1485
Olaya Herrera 3.4781785185, -76.512807093 1470
Guillermo Valencia 3.4744945902,  -76.513665400 1248
José Ignacio Rengifo 3.4716245430, -76.513665400 2160
Santo Tomás 3.4583022697,  -76.516454898 1776
La Merced 3.4627144903, -76.502464496 706
Pedro Antonio Molina 3.4828048267, -76.487615789 2369
Santa Librada 3.4622861203, -76.523020945 2498
República de Israel 3.4636569037, -76.510532580 1510
San Vicente Paul 3.4662271172, -76.509502612 2330
Manuel María Mallarino 3.4567601292, -76.488517010 1464
Sebastián de Belalcázar 3.4602299411,  -76.485212529 628
Liceo Departamental 3.4238604624,  -76.538556302 364
Libardo Madrid 3.4220611537,  -76.543834890 2439
Metropolitano Santa Anita 3.4016910381, -76.542182651 1815
San José 3.3969358164,  -76.550315108 2230

De acuerdo a la información disponible, es posible utilizar un mapa de calor como herramienta de análisis preliminar y búsqueda de alternativas de localización. Veamos.

Agregar una capa de mapa de calor

La API de Google Maps puede utilizarse de la misma manera en la que un sitio web incorpora un mapa tradicional a su plataforma (Javascript). También pueden utilizarse plataformas externas para su visualización como JSFiddle.

Lo primero que haremos es configurar el mapa sobre el cual se ubicarán los puntos:

let map, heatmap;

function initMap() {
  map = new google.maps.Map(document.getElementById("map"), {
    zoom: 13,
    center: { lat: 3.43, lng: -76.51 },
    mapTypeId: "satellite",
  });
  heatmap = new google.maps.visualization.HeatmapLayer({
    data: getPoints(),
    map: map,
  });
  document
    .getElementById("toggle-heatmap")
    .addEventListener("click", toggleHeatmap);
  document
    .getElementById("change-gradient")
    .addEventListener("click", changeGradient);
  document
    .getElementById("change-opacity")
    .addEventListener("click", changeOpacity);
  document
    .getElementById("change-radius")
    .addEventListener("click", changeRadius);
}

zoom: Indicará el nivel de cercanía inicial del mapa de acuerdo a su centro. De igual forma, como usuarios podemos utilizar los controles para acercar o alejar una vez tengamos la visualización.

center: Indicará las coordenadas centrales del mapa (latitud y longitud). En nuestro ejemplo hemos adicionado las coordenadas de la ciudad de Cali (lat: 3.43, lng: -76.51).

mapTypeId: Tipo de mapa a utilizar. Podemos elegir un mapa tipo relieve o un mapa satelital (satellite).

En este mapa utilizaremos algunas funciones que nos permitirán cambiar algunos atributos de visualización: degradado, opacidad, radio de calor. 

gradient: Corresponde al degradado de color del mapa de calor, de manera predeterminada degradará desde el rojo (máxima intensidad) hacia el verde. Sin embargo, usted puede configurar la matriz de colores del degradado. En nuestro ejemplo, permitiremos que el usuario haga un cambio en la configuración del degradado con un clic.

opacity: La opacidad corresponde a la transparencia de la capa del mapa de calor, expresada como un número entre 0 y 1. En nuestro ejemplo, permitiremos que el usuario haga un cambio en la configuración de la opacidad con un clic.

radius: Corresponde al radio de influencia de cada punto de datos, en píxeles. Este es uno de los atributos más importantes del mapa de calor, ya que a partir de su valor podremos visualizar mejor o no, la data correspondiente. En nuestro ejemplo, permitiremos que el usuario haga un cambio en la configuración del radio con un clic.

Cambio de atributos

Las siguientes líneas permitirán cambiar los atributos ya mencionados con un solo clic. A continuación se establecen los valores opcionales de cada atributo.

function toggleHeatmap() {
  heatmap.setMap(heatmap.getMap() ? null : map);
}

function changeGradient() {
  const gradient = [
    "rgba(0, 255, 255, 0)",
    "rgba(0, 255, 255, 1)",
    "rgba(0, 191, 255, 1)",
    "rgba(0, 127, 255, 1)",
    "rgba(0, 63, 255, 1)",
    "rgba(0, 0, 255, 1)",
    "rgba(0, 0, 223, 1)",
    "rgba(0, 0, 191, 1)",
    "rgba(0, 0, 159, 1)",
    "rgba(0, 0, 127, 1)",
    "rgba(63, 0, 91, 1)",
    "rgba(127, 0, 63, 1)",
    "rgba(191, 0, 31, 1)",
    "rgba(255, 0, 0, 1)",
  ];
  heatmap.set("gradient", heatmap.get("gradient") ? null : gradient);
}

function changeRadius() {
  heatmap.set("radius", heatmap.get("radius") ? null : 20);
}

function changeOpacity() {
  heatmap.set("opacity", heatmap.get("opacity") ? null : 5);
}

Data de entrada: Ubicaciones

A continuación se ingresarán las 50 ubicaciones de nuestro caso de ejemplo. Utilizaremos puntos ponderados, con coordenadas de latitud y longitud, y un peso determinado por la población estudiantil de cada punto.

function getPoints() {
  return [
    {location: new google.maps.LatLng(3.453591118286918, -76.52254885881977), weight: 1494},
    {location: new google.maps.LatLng(3.451577758085148, -76.51023215602375), weight: 908},
    {location: new google.maps.LatLng(3.4481079145332427, -76.51074714011278), weight: 697},
    {location: new google.maps.LatLng(3.4469941349057063, -76.51525325089182), weight: 1714},
    {location: new google.maps.LatLng(3.4479794015658674, -76.49993247424311), weight: 1731},
    {location: new google.maps.LatLng(3.4451521118907227, -76.49641341630138), weight: 2297},
    {location: new google.maps.LatLng(3.4373556029276764, -76.51383704461735), weight: 1265},
    {location: new google.maps.LatLng(3.4379553366684252, -76.52299947000571), weight: 1658},
    {location: new google.maps.LatLng(3.4330289411959662, -76.52707642704613), weight: 604},
    {location: new google.maps.LatLng(3.4334144860421287, -76.50720662416609), weight: 416},
    {location: new google.maps.LatLng(3.433157456127054, -76.52673310420856), weight: 1584},
    {location: new google.maps.LatLng(3.431786628745183, -76.51733464458373), weight: 2350},
    {location: new google.maps.LatLng(3.4306299916118603, -76.50360173554287), weight: 964},
    {location: new google.maps.LatLng(3.4290878065901618, -76.51660508379094), weight: 329},
    {location: new google.maps.LatLng(3.4250609784210844, -76.51488847016083), weight: 774},
    {location: new google.maps.LatLng(3.4166645586142086, -76.51673382932174), weight: 1818},
    {location: new google.maps.LatLng(3.419534771537968, -76.49591988905668), weight: 1530},
    {location: new google.maps.LatLng(3.41520802942298, -76.493237680305), weight: 2106},
    {location: new google.maps.LatLng(3.4157220988351096, -76.53383559476927), weight: 330},
    {location: new google.maps.LatLng(3.4130660706512925, -76.53984374247463), weight: 976},
    {location: new google.maps.LatLng(3.427031555952873, -76.55134505496746), weight: 1975},
    {location: new google.maps.LatLng(3.408053549563415, -76.50817222583817), weight: 936},
    {location: new google.maps.LatLng(3.431957663249241, -76.47495575209557), weight: 1563},
    {location: new google.maps.LatLng(3.400770815705138, -76.55177421321405), weight: 1219},
    {location: new google.maps.LatLng(3.3970865884759056, -76.54259032842468), weight: 1954},
    {location: new google.maps.LatLng(3.393316666803048, -76.53735465673438), weight: 399},
    {location: new google.maps.LatLng(3.387318718983735, -76.5197593748766), weight: 1741},
    {location: new google.maps.LatLng(3.3834202377137204, -76.52078934305466), weight: 1111},
    {location: new google.maps.LatLng(3.381278208361199, -76.52023144362487), weight: 1826},
    {location: new google.maps.LatLng(3.377208339558826, -76.52327843281832), weight: 1772},
    {location: new google.maps.LatLng(3.378150837005705, -76.54460735730136), weight: 1965},
    {location: new google.maps.LatLng(3.3935733137749238, -76.54932804783431), weight: 841},
    {location: new google.maps.LatLng(3.390745863684127, -76.55031510067163), weight: 770},
    {location: new google.maps.LatLng(3.3790932549330677, -76.54688187341141), weight: 650},
    {location: new google.maps.LatLng(3.4019699352880104, -76.51345082175563), weight: 1401},
    {location: new google.maps.LatLng(3.4030409276299833, -76.51731320242338), weight: 1474},
    {location: new google.maps.LatLng(3.4044546356985284, -76.52143307513562), weight: 1926},
    {location: new google.maps.LatLng(3.429601076750566, -76.53761216054455), weight: 1566},
    {location: new google.maps.LatLng(3.4454939428890783, -76.5016920200071), weight: 2354},
    {location: new google.maps.LatLng(3.4492208216317457, -76.50594063874162), weight: 2043},
    {location: new google.maps.LatLng(3.4422382667554077, -76.50988885009086), weight: 2333},
    {location: new google.maps.LatLng(3.4407817764607853, -76.51752778074483), weight: 696},
    {location: new google.maps.LatLng(3.435598366122187, -76.51645489840418), weight: 1073},
    {location: new google.maps.LatLng(3.431143181324255, -76.51272126375868), weight: 1275},
    {location: new google.maps.LatLng(3.48276199070547, -76.49976083030087), weight: 1485},
    {location: new google.maps.LatLng(3.4781785185724408, -76.51280709388969), weight: 1470},
    {location: new google.maps.LatLng(3.474494590235007, -76.51366540070475), weight: 1248},
    {location: new google.maps.LatLng(3.47162454307462, -76.51366540070475), weight: 2160},
    {location: new google.maps.LatLng(3.458302269741842, -76.51645489800703), weight: 1776},
    {location: new google.maps.LatLng(3.4627144903470133, -76.50246449692165), weight: 706},
    {location: new google.maps.LatLng(3.4828048267502214, -76.48761578902122), weight: 2369},
    {location: new google.maps.LatLng(3.4622861203152, -76.52302094514219), weight: 2498},
    {location: new google.maps.LatLng(3.4636569037348472, -76.51053258098315), weight: 1510},
    {location: new google.maps.LatLng(3.4662271172959103, -76.5095026128051), weight: 2330},
    {location: new google.maps.LatLng(3.4567601292443983, -76.4885170108912), weight: 1464},
    {location: new google.maps.LatLng(3.460229941169211, -76.48521252965324), weight: 628},
    {location: new google.maps.LatLng(3.423860462402868, -76.53855630259389), weight: 364},
    {location: new google.maps.LatLng(3.422061153775949, -76.54383489070575), weight: 2439},
    {location: new google.maps.LatLng(3.4016910381681438, -76.54218265181241), weight: 1815},
    {location: new google.maps.LatLng(3.396935816423716, -76.55031510890593), weight: 2230},
   
  ];
}

A partir de estas configuraciones y data de entrada, podemos obtener un mapa de calor soportado en Google Maps. Podemos ver este ejemplo en: Mapa de calor Google Maps Ejemplo.

El resultado será:

Podemos ocultar o visualizar la capa del mapa de calor; cambiar los colores del degradado; cambar el radio de intensidad de cada punto ponderado; y por último, cambiar la transparencia de la capa.

Así mismo, podemos considerar, por ejemplo, que la representación visual se encuentra muy dispersa y no nos permite tener una idea concluyente. Podemos intentar ampliando el radio (radius) de cada punto (en el código directamente), es decir, su influencia. De manera que nos permita una visualización con mayor densidad. Ampliando a 70 píxeles el radio del código anterior, tendríamos:

mapas de calor

A partir de esta imagen los tomadores de decisiones pueden tener una idea aproximada respecto a las zonas geográficas de mayor densidad poblacional. Al contrario de los algoritmos tradicionales, no obtendremos una coordenada específica (que probablemente conduzca a un lugar inhabitable o no disponible); tendremos zonas de densidad basadas en la ponderación deseada.

Podemos ampliar el zoom sobre una zona deseada y conocer los puntos específicos (con su intensidad respectiva):

mapas de calor

Aquí podemos ver con claridad la diferencia del peso ponderado de los puntos; aquellos puntos más intensos serán aquellas instituciones educativas con mayor población estudiantil (de acuerdo a nuestro caso). Podemos incluso, haciendo uso del registro de imágenes en campo de Google, revisar un sector en específico; revisar el estado de las vías, revisar si existen unidades habitables, entre otros:


Tal como lo hemos mencionado, los mapas de calor son no nos proporcionan como resultado una localización específica; nos proporcionan una visión de densidad basada en un factor de ponderación establecido. Además, es una herramienta dinámica, la cual puede integrarse con fuentes de datos diversas, que puede manipularse en un entorno geográfico real.

Es una herramienta que recomendamos para el análisis preliminar y la búsqueda de zonas de localización.

Sin embargo, al utilizar mapas de calor en entornos como por ejemplo Python, podemos integrar a esta herramienta, un método heurístico que nos proporcione una localización específica. Si quieres conocer un modelo que integra ambas herramientas, te invitamos a leer: Mapas de calor y Algoritmo de Centro de Gravedad utilizando Python.

Bryan Salazar López

Ingeniero Industrial, Magíster en Logística Integral, especializado en productividad, con interés y experiencia en el modelamiento de procesos bajo dimensiones de sostenibilidad, industria 4.0, transformación digital y modelos de optimización. Fundador de Ingenieriaindustrialonline.com, sitio donde se recogen las aportaciones de investigaciones, artículos y referencias.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.

Botón volver arriba
Nuestros partners recogerán datos y usarán cookies para ofrecerle anuncios personalizados y medir el rendimiento.    Ver Política de privacidad
Privacidad