Files
test/vermap.html
2025-12-09 00:20:32 +00:00

360 lines
15 KiB
HTML

<!DOCTYPE html>
<html>
<head>
<title>RLX Ver Helper</title>
<link rel="stylesheet" href="https://code.jquery.com/ui/1.13.1/themes/smoothness/jquery-ui.css">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
<!-- Make sure CSS is loaded before JS that might interact with the DOM -->
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://code.jquery.com/ui/1.13.1/jquery-ui.js" integrity="sha256-6XMVI0zB8cRzfZjqKcD01PBsAy3FlDASrlC8SxCpInY=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/chroma-js/2.4.2/chroma.min.js" integrity="sha512-zInFF17qBFVvvvFpIfeBzo7Tj7+rQxLeTJDmbxjBz5/zIr89YVbTNelNhdTT+/DCrxoVzBeUPVFJsczKbB7sew==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js" integrity="sha512-XQoYMqMTK8LvdxXYG3nZ448hOEQiglfqkJs1NOQV44cWnUrBc8PkAOcXy20w0vlaXaVUearIOBhiXZ5V3ynxwA==" crossorigin=""></script>
<script src="https://unpkg.com/file-saver@2.0.5/dist/FileSaver.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dom-to-image/2.6.0/dom-to-image.js" integrity="sha512-wUa0ktp10dgVVhWdRVfcUO4vHS0ryT42WOEcXjVVF2+2rcYBKTY7Yx7JCEzjWgPV+rj2EDUr8TwsoWF6IoIOPg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<script src="https://cdn.rawgit.com/hayeswise/Leaflet.PointInPolygon/v1.0.0/wise-leaflet-pip.js"></script>
<style type="text/css">
body {
padding: 0;
margin: 0;
}
html, body {
height: 100%;
width: 100%;
}
#mapid {
height: 95%;
/* background: none !important; */ /* Consider if !important is truly needed */
}
#bottombar {
/* height: 98%; */
}
.box {
position: absolute;
top: 225px;
z-index: 9999;
text-align: center;
width: 250px;
left: 10%;
margin-left: -75px; /* half of the width */
}
.box2 {
position: absolute;
top: 500px;
z-index: 9999;
text-align: center;
width: 250px;
left: 10%;
margin-left: -75px; /* half of the width */
}
input[type=number] {
width: 50px;
}
input[type=text] {
width: 150px;
}
.legend {
line-height: 18px;
color: #555;
}
.legend i {
width: 15px;
height: 15px;
float: left;
margin-right: 8px;
opacity: 0.7;
}
.info {
padding: 6px 8px;
font: 14px/16px Arial, Helvetica, sans-serif;
background: white;
background: rgba(255, 255, 255, 0.8);
box-shadow: 0 0 15px rgba(0, 0, 0, 0.2);
border-radius: 5px;
}
.info h4 {
margin: 0 0 5px;
color: #777;
}
#slider-2 {
position: absolute;
left: 20px;
top: 200px;
width: 300px;
}
#timeforsaveimages {
position: absolute;
left: 20px;
bottom: 20px;
color: black;
font-size: 30px;
}
#stats {
/* Style for stats if needed */
}
.my-label {
font-size: 10px; /* Note: 6px is very small */
/* font-weight: bold; */
/* background-color: transparent; */
border: 0px solid #ccc;
border-radius: 1px;
padding: 1px 2px;
}
</style>
</head>
<body>
<div class="box">
<div id="toggle">
<button id="archive" onclick="resetmap()">Reset Map</button><br>
Left click on zone to increment up, right click on zone to reset zone
</div>
</div>
<div id="slider-2"></div>
<div class="box2">
<div id="changelog">
</div>
</div>
<div id="mapid"></div>
<script>
var update_position_timeout = null;
function resetmap() {
$.get({
url: 'main.php?service=ver&reset=potato',
success: function () {
geoJSONcounties.setStyle({ fillColor: 'red' }); // Reset visually immediately
loadlsr(); // Reload data from server
},
error: function (xhr, error) {
console.error("Error resetting map:", error); // Log error
alert('Unable to reset map state, please refresh page');
}
});
}
// --- Leaflet Map Initialization ---
var mymap = L.map('mapid', {
zoomDelta: 0.25,
zoomSnap: 0.25, // Using 0.25 to match zoomDelta often makes sense
doubleClickZoom: false // *** THIS DISABLES DOUBLE CLICK ZOOM ***
}).setView([38.508, -81.652480], 8.0);
var geoJSONcounties = L.geoJSON(false, {
onEachFeature: function (feature, layer) {
// Use feature.properties.name or similar if available and more descriptive than shortname
layer.bindTooltip(feature.properties.shortname || 'Unnamed Zone', { permanent: true, direction: 'center', className: 'my-label' });
layer.on({
contextmenu: function (e) {
L.DomEvent.stopPropagation(e); // Prevent map context menu if any
L.DomEvent.preventDefault(e); // Prevent browser context menu
clickdown(feature, layer, e);
},
click: function (e) {
clickup(feature, layer, e);
},
});
},
style: function (feature) {
return {
fillColor: 'red', // Default color
color: 'navy',
weight: 3,
opacity: 1,
fillOpacity: 0.50
};
}
}).addTo(mymap);
function getColorValue(color) {
switch (String(color).toLowerCase()) { // Add String() for safety
case 'red': return 0;
case 'yellow': return 1;
case 'green': return 2;
default: return 0; // Default to red if color is unexpected
}
}
function vercolor(d) {
if (d == 0) return 'red';
if (d == 1) return 'yellow';
if (d >= 2) return 'green'; // Use >= 2 to catch any higher values
return 'red'; // Default color if d is unexpected (e.g., null, undefined, < 0)
}
function clickup(feature, layer, e) {
var zone = feature.properties.state_zone;
var currentLsrValue = getColorValue(layer.options.fillColor);
var newLsr = currentLsrValue + 1;
// Optional: Add logic to cap the max value if needed (e.g., if (newLsr > 2) newLsr = 2;)
$.get({
url: `main.php?service=ver&lsrs=potato&zone=${zone}&lsr=${newLsr}&dir=1`, // dir=1 seems specific to 'up'
success: function () {
layer.setStyle({ fillColor: vercolor(newLsr) });
// No need to call loadlsr() here, the server state is updated,
// and the visual state is updated directly. loadlsr() will refresh periodically anyway.
},
error: function (xhr, error) {
console.error("Error updating zone (up):", error);
alert('Unable to update zone, please try again or refresh.');
// Optional: Revert style if update fails?
// layer.setStyle({ fillColor: vercolor(currentLsrValue) });
}
});
}
function clickdown(feature, layer, e) {
var zone = feature.properties.state_zone;
// On right-click (contextmenu), reset the zone to 0 (red)
var newLsr = 0; // Reset to red
$.get({
url: `main.php?service=ver&lsrs=potato&zone=${zone}&lsr=${newLsr}`, // No dir needed? Or specific dir for reset?
success: function () {
layer.setStyle({ fillColor: vercolor(newLsr) });
// No need to call loadlsr() here
},
error: function (xhr, error) {
console.error("Error updating zone (down/reset):", error);
alert('Unable to reset zone, please try again or refresh.');
// Optional: Revert style if update fails?
// layer.setStyle({ fillColor: vercolor(getColorValue(layer.options.fillColor)) }); // Revert to original before click
}
});
}
function loadlsr() {
// Clear existing timeout *before* making the new request
if (update_position_timeout) {
clearTimeout(update_position_timeout); // Use clearTimeout for setTimeout
update_position_timeout = null; // Best practice to nullify after clearing
}
$.getJSON('https://wx.stoat.org/main.php?service=ver&lsrslist=potato')
.done(function (data) {
if (data && data.length > 0) {
var zoneData = {};
// Create a lookup map for efficiency
for (var i in data) {
if (data[i] && data[i].zone !== undefined && data[i].lsr !== undefined) {
zoneData[data[i].zone] = data[i].lsr;
}
}
geoJSONcounties.eachLayer(function (layer) {
var zone = layer.feature.properties.state_zone;
if (zoneData.hasOwnProperty(zone)) {
layer.setStyle({ fillColor: vercolor(zoneData[zone]) });
} else {
// Optional: Set a default color if zone not in data?
// layer.setStyle({ fillColor: 'grey' }); // Example default
}
});
} else {
// No data or empty data, maybe reset all to default?
console.log("No LSR data received or data is empty. Setting zones to default red.");
geoJSONcounties.setStyle({ fillColor: 'red' });
}
// Schedule the next update *after* the current one succeeded
update_position_timeout = setTimeout(loadlsr, 3000); // Re-schedule
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.error("Failed to load LSR data:", textStatus, errorThrown);
// Optionally, you might want to retry after a longer delay or stop polling
// For now, let's schedule the next attempt as usual, but log the error
update_position_timeout = setTimeout(loadlsr, 5000); // Maybe wait longer after failure
});
}
// var countiesjson = 'rlxtest.json'; // Local testing
var countiesjson = 'https://wx.stoat.org/main.php?service=ver'; // Production endpoint
function initial_county_load() {
geoJSONcounties.clearLayers();
$.getJSON(countiesjson)
.done(function (data) {
if(data && data.features) { // Basic check if data looks like GeoJSON
geoJSONcounties.addData(data);
geoJSONcounties.bringToBack();
loadlsr(); // Load the initial LSR states after counties are drawn
} else {
console.error("Received invalid GeoJSON data for counties.");
alert("Error: Could not load county boundaries.");
}
})
.fail(function (jqXHR, textStatus, errorThrown) {
console.error("Failed to load initial county GeoJSON:", textStatus, errorThrown);
alert("Fatal Error: Could not load county boundaries. Please refresh the page.");
});
}
// --- Base Layers ---
var Esri_WorldStreetMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri'
});
var Esri_WorldImagery = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community'
});
var Esri_WorldTopoMap = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
attribution: 'Tiles © Esri — Esri, DeLorme, NAVTEQ, TomTom, Intermap, iPC, USGS, FAO, NPS, NRCAN, GeoBase, Kadaster NL, Ordnance Survey, Esri Japan, METI, Esri China (Hong Kong), and the GIS User Community'
});
var CartoDB_Positron = L.tileLayer('https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png', {
attribution: '© <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors © <a href="https://carto.com/attributions">CARTO</a>',
subdomains: 'abcd',
maxZoom: 20
});
var USGS_USImageryTopo = L.tileLayer('https://basemap.nationalmap.gov/arcgis/rest/services/USGSImageryTopo/MapServer/tile/{z}/{y}/{x}', {
maxZoom: 20,
attribution: 'Tiles courtesy of the <a href="https://usgs.gov/">U.S. Geological Survey</a>'
});
var baselayers = {
"Black and White": CartoDB_Positron,
"Esri Street Map": Esri_WorldStreetMap,
"Esri Satellite": Esri_WorldImagery,
"Esri Topo": Esri_WorldTopoMap,
"USGS Sat/Topo": USGS_USImageryTopo,
};
L.control.layers(baselayers, null, { collapsed: false }).addTo(mymap);
CartoDB_Positron.addTo(mymap); // Set default base layer
// --- Initial Load ---
initial_county_load(); // Load counties first, then load LSR data
</script>
</body>
</html>