237 lines
5.6 KiB
HTML
237 lines
5.6 KiB
HTML
|
|
<!DOCTYPE html>
|
|
<html lang="en">
|
|
<head>
|
|
<base target="_top">
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
|
|
<title>Quick Start - Leaflet</title>
|
|
|
|
<link rel="shortcut icon" type="image/x-icon" href="docs/images/favicon.ico" />
|
|
|
|
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
|
|
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
|
|
|
|
<style>
|
|
html, body {
|
|
height: 100%;
|
|
margin: 0;
|
|
}
|
|
.leaflet-container {
|
|
height: 400px;
|
|
width: 600px;
|
|
max-width: 100%;
|
|
max-height: 100%;
|
|
}
|
|
</style>
|
|
|
|
|
|
</head>
|
|
<body>
|
|
|
|
<div id="control">
|
|
<button onclick="aktifkanMode()">Gambar Jalan</button>
|
|
<button onclick="simpanPolyline()">Simpan Jalan</button>
|
|
<button onclick="resetPolyline()">Reset</button>
|
|
</div>
|
|
|
|
<div id="map" style="width: 1000px; height: 600px;"></div>
|
|
|
|
<script>
|
|
const map = L.map('map').setView([-0.059502, 109.3462785], 16);
|
|
|
|
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
|
|
maxZoom: 19,
|
|
attribution: '© <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a>'
|
|
}).addTo(map);
|
|
|
|
let modeGambar = false;
|
|
let titikPolyline = [];
|
|
let polylineSementara = null;
|
|
let titikMarkers = [];
|
|
|
|
function aktifkanMode() {
|
|
modeGambar = true;
|
|
}
|
|
|
|
function resetPolyline() {
|
|
titikPolyline = [];
|
|
if (polylineSementara) {
|
|
map.removeLayer(polylineSementara);
|
|
polylineSementara = null;
|
|
}
|
|
|
|
titikMarkers.forEach(m => map.removeLayer(m));
|
|
titikMarkers = [];
|
|
}
|
|
|
|
const marker = L.marker([-0.059502, 109.34626578]).addTo(map)
|
|
.bindPopup('<b>Hello world!</b><br />I am a popup.').openPopup();
|
|
|
|
const circle = L.circle([-0.059502, 109.346544546], {
|
|
color: 'red',
|
|
fillColor: '#f03',
|
|
fillOpacity: 0.5,
|
|
radius: 500
|
|
}).addTo(map).bindPopup('I am a circle.');
|
|
|
|
const polygon = L.polygon([
|
|
[-0.0595334, 109.346224],
|
|
[-0.0577872, 109.34999],
|
|
[-0.059872, 109.3476675]
|
|
]).addTo(map).bindPopup('I am a polygon.');
|
|
|
|
|
|
const popup = L.popup()
|
|
.setLatLng([-0.059502, 109.3462785])
|
|
.setContent('I am a standalone popup.')
|
|
.openOn(map);
|
|
|
|
map.on('click', function(e) {
|
|
if (!modeGambar) return;
|
|
|
|
const latlng = e.latlng;
|
|
|
|
titikPolyline.push([latlng.lat, latlng.lng]);
|
|
|
|
const markerTitik = L.circleMarker([latlng.lat, latlng.lng], {
|
|
radius: 5,
|
|
color: 'black',
|
|
fillColor: 'yellow',
|
|
fillOpacity: 1
|
|
}).addTo(map);
|
|
|
|
titikMarkers.push(markerTitik);
|
|
|
|
if (polylineSementara) {
|
|
map.removeLayer(polylineSementara);
|
|
}
|
|
|
|
polylineSementara = L.polyline(titikPolyline, {
|
|
color: 'blue'
|
|
}).addTo(map);
|
|
});
|
|
|
|
function simpanPolyline() {
|
|
if (titikPolyline.length < 2) {
|
|
alert("Minimal 2 titik!");
|
|
return;
|
|
}
|
|
|
|
const form = `
|
|
<form onsubmit="prosesSimpanPolyline(event)">
|
|
<label>Nama Jalan:</label><br>
|
|
<input type="text" id="namaJalan" required><br><br>
|
|
|
|
<label>Status Jalan:</label><br>
|
|
<select id="statusJalan">
|
|
<option value="Nasional">Nasional</option>
|
|
<option value="Provinsi">Provinsi</option>
|
|
<option value="Kabupaten">Kabupaten</option>
|
|
</select><br><br>
|
|
|
|
<button type="submit">Simpan</button>
|
|
</form>
|
|
`;
|
|
|
|
L.popup()
|
|
.setLatLng(titikPolyline[titikPolyline.length - 1])
|
|
.setContent(form)
|
|
.openOn(map);
|
|
}
|
|
|
|
function hitungPanjang(koordinat) {
|
|
let total = 0;
|
|
|
|
for (let i = 0; i < koordinat.length - 1; i++) {
|
|
let p1 = L.latLng(koordinat[i][0], koordinat[i][1]);
|
|
let p2 = L.latLng(koordinat[i + 1][0], koordinat[i + 1][1]);
|
|
|
|
total += map.distance(p1, p2);
|
|
}
|
|
|
|
return total;
|
|
}
|
|
|
|
function prosesSimpanPolyline(event) {
|
|
event.preventDefault();
|
|
|
|
let nama = document.getElementById("namaJalan").value;
|
|
let status = document.getElementById("statusJalan").value;
|
|
let panjang = hitungPanjang(titikPolyline);
|
|
|
|
const dataBaru = {
|
|
nama: nama,
|
|
koordinat: titikPolyline,
|
|
status: status,
|
|
panjang: panjang
|
|
};
|
|
|
|
let data = JSON.parse(localStorage.getItem("jalan")) || [];
|
|
data.push(dataBaru);
|
|
|
|
localStorage.setItem("jalan", JSON.stringify(data));
|
|
|
|
alert("Jalan berhasil disimpan!");
|
|
|
|
map.closePopup();
|
|
resetPolyline();
|
|
modeGambar = false;
|
|
loadData();
|
|
}
|
|
|
|
function hapusJalan(index) {
|
|
let data = JSON.parse(localStorage.getItem("jalan")) || [];
|
|
|
|
data.splice(index, 1);
|
|
|
|
localStorage.setItem("jalan", JSON.stringify(data));
|
|
|
|
alert("Jalan dihapus!");
|
|
|
|
loadData();
|
|
}
|
|
|
|
function loadData() {
|
|
|
|
map.eachLayer(layer => {
|
|
if (layer instanceof L.Polyline && !(layer instanceof L.Polygon)) {
|
|
map.removeLayer(layer);
|
|
}
|
|
});
|
|
|
|
let dataJalan = JSON.parse(localStorage.getItem("jalan")) || [];
|
|
|
|
dataJalan.forEach((j, index) => {
|
|
|
|
let warna;
|
|
|
|
if (j.status === "Nasional") {
|
|
warna = "red";
|
|
} else if (j.status === "Provinsi") {
|
|
warna = "blue";
|
|
} else {
|
|
warna = "green";
|
|
}
|
|
|
|
let panjangM = j.panjang.toFixed(2);
|
|
|
|
L.polyline(j.koordinat, {
|
|
color: warna,
|
|
weight: 5
|
|
}).addTo(map).bindPopup(`
|
|
<b>${j.nama}</b><br>
|
|
<b>Status:</b> ${j.status}<br><br>
|
|
Panjang: ${panjangM} m<br><br>
|
|
<button onclick="hapusJalan(${index})">Hapus</button>
|
|
`);
|
|
});
|
|
}
|
|
|
|
loadData();
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|