Overview
The map integration displays property locations using OpenStreetMap with:
- Embedded interactive map with marker
- Link to Google Maps for navigation
- Fallback to address-based search when coordinates are unavailable
- Responsive iframe rendering
HTML Structure
From index.html:185-197, the location section:
<section class="bg-white dark:bg-slate-800 p-8 rounded-2xl shadow-sm border border-slate-100 dark:border-slate-700">
<div class="flex justify-between items-center mb-6">
<h3 class="text-xl font-display font-bold flex items-center gap-2">
<span class="material-icons-outlined text-primary">map</span>
Ubicación
</h3>
<a id="property-map" class="text-primary text-sm font-semibold flex items-center gap-1 hover:underline" href="#" target="_blank" rel="noopener">
Ver en Google Maps <span class="material-icons-outlined text-xs">open_in_new</span>
</a>
</div>
<p id="property-address" class="text-slate-500 dark:text-slate-400 text-sm mb-4">Dirección no disponible</p>
<div id="property-map-preview" class="w-full h-[300px] bg-slate-200 dark:bg-slate-700 rounded-xl relative overflow-hidden"></div>
</section>
renderMap() Function
From app.js:531-569, this function handles both OpenStreetMap embedding and Google Maps linking:
const renderMap = (property) => {
const address = [property.direccion, property.barrio, property.ciudad]
.filter(Boolean)
.join(", ");
const mapLink = $("#property-map");
const mapPreview = $("#property-map-preview");
const coords = property.latitud && property.longitud
? `${property.latitud},${property.longitud}`
: null;
$("#property-address").textContent = address || "Dirección no disponible";
// Google Maps link (for navigation)
const mapUrl = coords
? `https://www.google.com/maps/search/?api=1&query=${coords}`
: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(address)}`;
mapLink.href = mapUrl;
// OpenStreetMap embed (for preview)
if (coords) {
const [lat, lon] = coords.split(",");
const delta = 0.01;
const left = parseFloat(lon) - delta;
const right = parseFloat(lon) + delta;
const top = parseFloat(lat) + delta;
const bottom = parseFloat(lat) - delta;
const iframe = document.createElement("iframe");
iframe.src = `https://www.openstreetmap.org/export/embed.html?bbox=${left}%2C${bottom}%2C${right}%2C${top}&layer=mapnik&marker=${lat}%2C${lon}`;
iframe.loading = "lazy";
iframe.referrerPolicy = "no-referrer-when-downgrade";
iframe.title = "Mapa de ubicación";
iframe.style.border = "0";
iframe.style.width = "100%";
iframe.style.height = "100%";
mapPreview.innerHTML = "";
mapPreview.appendChild(iframe);
} else {
mapPreview.textContent = "Ubicación aproximada";
}
};
The address is constructed from multiple property fields:
const address = [property.direccion, property.barrio, property.ciudad]
.filter(Boolean)
.join(", ");
Example
Given:
property = {
direccion: "Calle 123 #45-67",
barrio: "Chicó",
ciudad: "Bogotá"
}
Output:
"Calle 123 #45-67, Chicó, Bogotá"
The filter(Boolean) removes any null, undefined, or empty string values before joining.
Coordinate Handling
The function checks for both latitude and longitude:
const coords = property.latitud && property.longitud
? `${property.latitud},${property.longitud}`
: null;
Both coordinates must be present for coordinate-based display.
Google Maps Integration
The “Ver en Google Maps” link uses Google Maps Search API:
With Coordinates
const mapUrl = coords
? `https://www.google.com/maps/search/?api=1&query=${coords}`
: `https://www.google.com/maps/search/?api=1&query=${encodeURIComponent(address)}`;
URL Examples
https://www.google.com/maps/search/?api=1&query=4.6097,-74.0817
OpenStreetMap Embedding
When coordinates are available, an interactive map is embedded:
Bounding Box Calculation
const delta = 0.01;
const left = parseFloat(lon) - delta;
const right = parseFloat(lon) + delta;
const top = parseFloat(lat) + delta;
const bottom = parseFloat(lat) - delta;
The delta value (0.01 degrees) creates approximately a 1km × 1km viewing area around the property.
Adjust the delta value to zoom in (smaller) or out (larger). For reference:
- 0.005 ≈ 500m × 500m (closer)
- 0.01 ≈ 1km × 1km (default)
- 0.02 ≈ 2km × 2km (wider)
Iframe Construction
const iframe = document.createElement("iframe");
iframe.src = `https://www.openstreetmap.org/export/embed.html?bbox=${left}%2C${bottom}%2C${right}%2C${top}&layer=mapnik&marker=${lat}%2C${lon}`;
iframe.loading = "lazy";
iframe.referrerPolicy = "no-referrer-when-downgrade";
iframe.title = "Mapa de ubicación";
iframe.style.border = "0";
iframe.style.width = "100%";
iframe.style.height = "100%";
mapPreview.innerHTML = "";
mapPreview.appendChild(iframe);
OpenStreetMap URL Parameters
| Parameter | Value | Description |
|---|
bbox | left,bottom,right,top | Bounding box coordinates |
layer | mapnik | Map rendering layer |
marker | lat,lon | Marker position |
Example URL
https://www.openstreetmap.org/export/embed.html?
bbox=-74.0917%2C4.5997%2C-74.0717%2C4.6197&
layer=mapnik&
marker=4.6097%2C-74.0817
Fallback Behavior
When coordinates are not available:
if (coords) {
// Render iframe with map
} else {
mapPreview.textContent = "Ubicación aproximada";
}
The preview area shows placeholder text instead of a map.
The iframe uses lazy loading:
This defers loading the map until it’s near the viewport, improving initial page load time.
Security Attributes
iframe.referrerPolicy = "no-referrer-when-downgrade";
This privacy setting controls what referrer information is sent to OpenStreetMap.
Responsive Sizing
The map container has a fixed height with responsive width:
<div id="property-map-preview" class="w-full h-[300px] bg-slate-200 dark:bg-slate-700 rounded-xl relative overflow-hidden"></div>
- Width: 100% of parent container
- Height: Fixed at 300px
- Background: Light/dark mode compatible placeholder color
Complete Example
With Full Coordinates
const property = {
direccion: "Carrera 7 #71-21",
barrio: "Chapinero",
ciudad: "Bogotá",
latitud: 4.6533,
longitud: -74.0602
};
renderMap(property);
Result:
- Address: “Carrera 7 #71-21, Chapinero, Bogotá”
- Google Maps link:
https://www.google.com/maps/search/?api=1&query=4.6533,-74.0602
- Embedded OpenStreetMap with marker at (4.6533, -74.0602)
Without Coordinates
const property = {
direccion: "Carrera 7 #71-21",
barrio: "Chapinero",
ciudad: "Bogotá"
};
renderMap(property);
Result:
- Address: “Carrera 7 #71-21, Chapinero, Bogotá”
- Google Maps link:
https://www.google.com/maps/search/?api=1&query=Carrera%207%20%2371-21%2C%20Chapinero%2C%20Bogot%C3%A1
- Preview shows: “Ubicación aproximada”
Why OpenStreetMap?
No API Key Required
Unlike Google Maps embed, OpenStreetMap doesn’t require authentication
Open Source
Free to use with no usage limits or billing
Privacy Friendly
No tracking or data collection by default
Lightweight
Simple iframe embed with minimal overhead