https://github.com/Leaflet/Leaflet
https://github.com/smeijer/leaflet-geosearch
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /> | |
<title>Display a map</title> | |
<link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" /> | |
<script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script> | |
<link rel="stylesheet" | |
href="https://cdn.jsdelivr.net/npm/[email protected]/dist/L.Control.Locate.min.css" /> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/L.Control.Locate.min.js" | |
charset="utf-8"></script> | |
<script src="https://unpkg.com/leaflet-providers@latest/leaflet-providers.js"></script> | |
<link rel="stylesheet" href="https://unpkg.com/leaflet-geosearch@latest/dist/geosearch.css" /> | |
<script src="https://unpkg.com/leaflet-geosearch@latest/dist/bundle.min.js"></script> | |
<link href="https://maxcdn.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" rel="stylesheet"> | |
<script src="https://cdn.jsdelivr.net/npm/[email protected]/src/L.Control.Sidebar.min.js"></script> | |
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/src/L.Control.Sidebar.min.css"> | |
<style> | |
#map { | |
position: absolute; | |
top: 0; | |
right: 0; | |
bottom: 0; | |
left: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="sidebar"> | |
<h1>Details</h1> | |
</div> | |
<div id="map" class="sidebar-map"> | |
</div> | |
<p> | |
<a href="https://www.openstreetmap.org/copyright" target="_blank" rel="noopener">© OpenStreetMap | |
contributors</a> | |
</p> | |
<script> | |
/** set default coord & zoom **/ | |
const map = L.map('map', { | |
// minZoom: 0, | |
// maxZoom: 25 | |
}).setView([-0.8674005, 131.3051903], 12.9); | |
/** set map tile endpoint **/ | |
L.tileLayer(`https://tile.openstreetmap.org/{z}/{x}/{y}.{ext}`, { | |
// tileSize: 512, | |
// zoomOffset: -1, | |
// minZoom: 1, | |
ext: 'png', | |
// minZoom: 0, | |
// maxZoom: 20, | |
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors', | |
crossOrigin: true | |
}).addTo(map); | |
/** set style **/ | |
L.tileLayer.provider('OpenStreetMap.Mapnik').addTo(map); | |
/** add sidebar **/ | |
var sidebar = L.control.sidebar('sidebar', { | |
position: 'right' | |
}); | |
map.addControl(sidebar); | |
/** set current location **/ | |
const lc = L.control.locate({ | |
locateOptions: { enableHighAccuracy: true } | |
}).addTo(map); | |
/** set searchbox location **/ | |
const search = new GeoSearch.GeoSearchControl({ | |
provider: new GeoSearch.OpenStreetMapProvider(), | |
style: 'bar', | |
maxMarkers: 1, // optional: number - default 1 | |
retainZoomLevel: false, // optional: true|false - default false | |
animateZoom: true, // optional: true|false - default true | |
autoClose: false, // optional: true|false - default false | |
searchLabel: 'Pencarian', // optional: string - default 'Enter address' | |
keepResult: false, // optional: true|false - default false | |
updateMap: true, // optional: true|false - default true | |
showMarker: true, // optional: true|false - default true | |
showPopup: false, // optional: true|false - default false | |
popupFormat: ({ query, result }) => result.label, // optional: function - default returns result label, | |
resultFormat: ({ result }) => result.label, // optional: function - default returns result label | |
marker: { | |
// optional: L.Marker - default L.Icon.Default | |
icon: new L.Icon.Default(), | |
draggable: false, | |
} | |
}); | |
map.addControl(search); | |
var marker; | |
const hideKey = [ | |
'place_id', | |
'osm_type', | |
'osm_id', | |
'place_rank', | |
'importance', | |
'licence', | |
'boundingbox']; | |
/** | |
* @param {Object} coord | |
* @param {number} coord.lat | |
* @param {number} coord.lg | |
**/ | |
const getMapDetails = async ({ lat = -0.8674005, lng = 131.3051903 }) => { | |
if (marker) | |
map.removeLayer(marker); | |
marker = L.marker({ lat: lat, lng: lng }).addTo(map); | |
try { | |
var details = | |
await (await fetch(`https://nominatim.openstreetmap.org/reverse?lat=${lat}&lon=${lng}&format=json`)) | |
.json() | |
// show json content | |
var content = `<h1>Details</h1>` + Object.entries(details).map(([key, value]) => { | |
if (hideKey.includes(key)) | |
return ''; | |
else if (key === 'address') | |
return Object.entries(value).map(([k, v]) => | |
`<div style="padding-bottom: 8px"><div style="font-weight: bold;"> ${k} </div><span>${v}</span></div>`).join(''); | |
else return `<div style="padding-bottom: 8px"><div style="font-weight: bold;"> ${key} </div><span>${value}</span></div>`; | |
}).join(''); | |
sidebar.setContent(content); | |
sidebar.show(); | |
// TODO: | |
// save details json data | |
} catch (error) { | |
alert('Terjadi kesalahan'); | |
} | |
} | |
/** event handle **/ | |
map.on('geosearch/showlocation', async (e) => | |
getMapDetails({ lat: e.location.y, lng: e.location.x })); | |
map.on('click', (e) => | |
setTimeout(async () => | |
await getMapDetails({ lat: e.latlng.lat, lng: e.latlng.lng }), 1000)); | |
/** start get current location **/ | |
// lc.start(); | |
</script> | |
</body> | |
</html> |