234 lines
7.7 KiB
JavaScript
234 lines
7.7 KiB
JavaScript
/**
|
|
* MAPS FORM CUSTOM - MAPLIBRE VERSION
|
|
* Menggunakan Style Google Maps (Raster)
|
|
*/
|
|
|
|
var map, marker;
|
|
var currentStyle = 'hybrid'; // Default style
|
|
|
|
// --- DEFINISI STYLE GOOGLE MAPS ---
|
|
const googleHybridStyle = {
|
|
'version': 8,
|
|
'sources': {
|
|
'google-hybrid': {
|
|
'type': 'raster',
|
|
'tiles': ['https://mt1.google.com/vt/lyrs=y&x={x}&y={y}&z={z}'],
|
|
'tileSize': 256,
|
|
'attribution': '© Google Maps'
|
|
}
|
|
},
|
|
'layers': [{
|
|
'id': 'google-hybrid-layer',
|
|
'type': 'raster',
|
|
'source': 'google-hybrid',
|
|
'minzoom': 0,
|
|
'maxzoom': 22
|
|
}]
|
|
};
|
|
|
|
const googleStreetStyle = {
|
|
'version': 8,
|
|
'sources': {
|
|
'google-street': {
|
|
'type': 'raster',
|
|
'tiles': ['https://mt1.google.com/vt/lyrs=m&x={x}&y={y}&z={z}'],
|
|
'tileSize': 256,
|
|
'attribution': '© Google Maps'
|
|
}
|
|
},
|
|
'layers': [{
|
|
'id': 'google-street-layer',
|
|
'type': 'raster',
|
|
'source': 'google-street',
|
|
'minzoom': 0,
|
|
'maxzoom': 22
|
|
}]
|
|
};
|
|
|
|
function initMap() {
|
|
var latitudeInput = document.getElementById('latitude').value;
|
|
var longitudeInput = document.getElementById('longitude').value;
|
|
|
|
// Cek input awal
|
|
if (latitudeInput && longitudeInput) {
|
|
var pos = {
|
|
lat: parseFloat(latitudeInput),
|
|
lng: parseFloat(longitudeInput)
|
|
};
|
|
initMapWithPos(pos);
|
|
} else {
|
|
// Coba Geolocation
|
|
if (navigator.geolocation) {
|
|
navigator.geolocation.getCurrentPosition(function(position) {
|
|
var pos = {
|
|
lat: position.coords.latitude,
|
|
lng: position.coords.longitude
|
|
};
|
|
initMapWithPos(pos);
|
|
updateFormInputs(pos.lat, pos.lng);
|
|
}, function() {
|
|
console.warn("⚠️ Geolocation gagal, fallback ke Jakarta");
|
|
handleLocationError(true);
|
|
initMapWithPos({ lat: -6.2, lng: 106.816666 });
|
|
});
|
|
} else {
|
|
console.warn("⚠️ Browser tidak support geolocation, fallback ke Jakarta");
|
|
handleLocationError(false);
|
|
initMapWithPos({ lat: -6.2, lng: 106.816666 });
|
|
}
|
|
}
|
|
}
|
|
|
|
function initMapWithPos(pos) {
|
|
// Init MapLibre
|
|
map = new maplibregl.Map({
|
|
container: 'map',
|
|
style: googleHybridStyle, // Default Hybrid
|
|
center: [pos.lng, pos.lat], // INGAT: MapLibre urutannya [Lng, Lat]
|
|
zoom: 10,
|
|
attributionControl: true,
|
|
dragRotate: false,
|
|
pitchWithRotate: false,
|
|
touchPitch: false
|
|
});
|
|
|
|
// Kontrol Navigasi (Zoom & Compass)
|
|
map.addControl(new maplibregl.NavigationControl({ showCompass: false, showZoom: true }), 'top-right');
|
|
map.addControl(new maplibregl.FullscreenControl(), 'top-left');
|
|
|
|
// Kontrol Lokasi Saya (Geolocate)
|
|
const geolocateControl = new maplibregl.GeolocateControl({
|
|
positionOptions: { enableHighAccuracy: true },
|
|
trackUserLocation: true,
|
|
showUserHeading: true
|
|
});
|
|
map.addControl(geolocateControl, 'top-left');
|
|
|
|
// Event saat lokasi ditemukan via tombol
|
|
geolocateControl.on('geolocate', function(e) {
|
|
var lat = e.coords.latitude;
|
|
var lng = e.coords.longitude;
|
|
updateMarker(lat, lng);
|
|
updateFormInputs(lat, lng);
|
|
});
|
|
|
|
// Tambahkan Tombol Ganti Layer (Satelit/Jalan)
|
|
addLayerSwitcher();
|
|
|
|
// Tunggu map load sebelum pasang marker awal
|
|
map.on('load', function() {
|
|
updateMarker(pos.lat, pos.lng);
|
|
});
|
|
|
|
// Klik peta → pindah marker
|
|
map.on('click', function(e) {
|
|
// e.lngLat berisi {lng, lat}
|
|
var latitude = e.lngLat.lat.toFixed(6);
|
|
var longitude = e.lngLat.lng.toFixed(6);
|
|
updateMarker(latitude, longitude);
|
|
updateFormInputs(latitude, longitude);
|
|
});
|
|
}
|
|
|
|
// Fungsi Custom Switch Layer
|
|
function addLayerSwitcher() {
|
|
class LayerSwitchControl {
|
|
onAdd(map) {
|
|
this._map = map;
|
|
this._container = document.createElement('div');
|
|
this._container.className = 'maplibregl-ctrl maplibregl-ctrl-group';
|
|
|
|
const btn = document.createElement('button');
|
|
btn.innerHTML = '🗺️';
|
|
btn.title = "Ganti Tampilan Peta";
|
|
btn.type = "button";
|
|
btn.onclick = () => {
|
|
if (currentStyle === 'hybrid') {
|
|
map.setStyle(googleStreetStyle);
|
|
currentStyle = 'street';
|
|
} else {
|
|
map.setStyle(googleHybridStyle);
|
|
currentStyle = 'hybrid';
|
|
}
|
|
};
|
|
this._container.appendChild(btn);
|
|
return this._container;
|
|
}
|
|
onRemove() {
|
|
this._container.parentNode.removeChild(this._container);
|
|
this._map = undefined;
|
|
}
|
|
}
|
|
map.addControl(new LayerSwitchControl(), 'top-right');
|
|
}
|
|
|
|
function updateMarker(latitude, longitude) {
|
|
// MapLibre Marker menggunakan DOM Element, bukan icon image object
|
|
if (marker) {
|
|
marker.setLngLat([longitude, latitude]); // [Lng, Lat]
|
|
|
|
// Update popup
|
|
const popup = marker.getPopup();
|
|
if(popup) popup.setHTML("Lokasi terpilih");
|
|
else marker.setPopup(new maplibregl.Popup().setHTML("Lokasi terpilih")).togglePopup();
|
|
|
|
} else {
|
|
// Buat marker baru warna merah default
|
|
marker = new maplibregl.Marker({ color: '#D9534F' })
|
|
.setLngLat([longitude, latitude])
|
|
.setPopup(new maplibregl.Popup().setHTML("Lokasi terpilih"))
|
|
.addTo(map);
|
|
marker.togglePopup();
|
|
}
|
|
|
|
// Animasi terbang ke lokasi baru
|
|
map.flyTo({ center: [longitude, latitude], zoom: 17 });
|
|
}
|
|
|
|
function updateFormInputs(latitude, longitude) {
|
|
document.getElementById('latitude').value = latitude;
|
|
document.getElementById('longitude').value = longitude;
|
|
document.getElementById('latlong').value = `${latitude}, ${longitude}`;
|
|
}
|
|
|
|
function handleLocationError(browserHasGeolocation) {
|
|
console.error(browserHasGeolocation ?
|
|
'❌ Error: Geolocation service failed.' :
|
|
'❌ Error: Browser tidak support geolocation.');
|
|
}
|
|
|
|
// Sinkronisasi input form ⇄ peta
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
initMap();
|
|
const latlongInput = document.getElementById('latlong');
|
|
const latitudeInput = document.querySelector('input[data-maps="latitude"]') || document.getElementById('latitude');
|
|
const longitudeInput = document.querySelector('input[data-maps="longitude"]') || document.getElementById('longitude');
|
|
|
|
// Set nilai awal jika ada
|
|
if (latitudeInput.value && longitudeInput.value) {
|
|
latlongInput.value = `${latitudeInput.value}, ${longitudeInput.value}`;
|
|
}
|
|
|
|
// Listener Input Manual LatLong (Format: lat, long)
|
|
latlongInput.addEventListener('input', function() {
|
|
const latlongValue = latlongInput.value.split(',');
|
|
const latLongRegex = /^(-?\d+(\.\d+)?),\s*(-?\d+(\.\d+)?)$/;
|
|
|
|
if (latLongRegex.test(latlongInput.value.trim())) {
|
|
if (latlongValue.length === 2) {
|
|
const lat = parseFloat(latlongValue[0].trim());
|
|
const long = parseFloat(latlongValue[1].trim());
|
|
latitudeInput.value = lat;
|
|
longitudeInput.value = long;
|
|
updateMarker(lat, long);
|
|
}
|
|
}
|
|
});
|
|
|
|
latitudeInput.addEventListener('input', function() {
|
|
latlongInput.value = `${latitudeInput.value}, ${longitudeInput.value}`;
|
|
});
|
|
longitudeInput.addEventListener('input', function() {
|
|
latlongInput.value = `${latitudeInput.value}, ${longitudeInput.value}`;
|
|
});
|
|
}); |