// ==UserScript==
// @name Nepali WMS layers
// @version 2025.12.27.03
// @author kid4rm90s
// @description Displays layers from Nepali WMS services in WME
// @match https://*.waze.com/*/editor*
// @match https://*.waze.com/editor
// @exclude https://*.waze.com/user/editor*
// @run-at document-end
// @namespace https://greasyfork.org/en/users/1087400-kid4rm90s
// @license MIT
// @grant GM_xmlhttpRequest
// @require https://greasyfork.org/scripts/560385/code/WazeToastr.js
// @require https://update.greasyfork.icu/scripts/516445/1480246/Make%20GM%20xhr%20more%20parallel%20again.js
// @connect geoserver.softwel.com.np
// @connect admin.nationalgeoportal.gov.np
// @connect localhost:8080
// @connect greasyfork.org
// @downloadURL https://update.greasyfork.icu/scripts/521924/Nepali%20WMS%20layers.user.js
// @updateURL https://update.greasyfork.icu/scripts/521924/Nepali%20WMS%20layers.meta.js
// ==/UserScript==
/* Scripts modified from Czech WMS layers (https://greasyfork.org/cs/scripts/35069-czech-wms-layers; https://greasyfork.org/en/scripts/34720-private-czech-wms-layers, https://greasyfork.org/en/scripts/28160)
orgianl authors: petrjanik, d2-mac, MajkiiTelini, and Croatian WMS layers (https://greasyfork.org/en/scripts/519676-croatian-wms-layers) author: JS55CT */
/* global W */
/* global WazeToastr */
/* global $ */
/* global OpenLayers */
/* global require */
(function main() {
('use strict');
const updateMessage = 'Fixed :
- Temporary fix for alerts not displaying properly.';
const scriptName = GM_info.script.name;
const scriptVersion = GM_info.script.version;
const downloadUrl = 'https://greasyfork.org/scripts/521924-nepali-wms-layers/code/nepali-wms-layers.user.js';
let wmeSDK;
var WMSLayersTechSource = {};
var W;
var OL;
var I18n;
var ZIndexes = {};
var WMSLayerTogglers = {};
async function init() {
console.log(`${scriptName} initializing.`);
W = unsafeWindow.W;
OL = unsafeWindow.OpenLayers;
I18n = unsafeWindow.I18n;
WMSLayersTechSource.tileSizeG = new OL.Size(512, 512);
WMSLayersTechSource.resolutions = [
156543.03390625, 78271.516953125, 39135.7584765625, 19567.87923828125, 9783.939619140625, 4891.9698095703125, 2445.9849047851562, 1222.9924523925781, 611.4962261962891, 305.74811309814453, 152.87405654907226, 76.43702827453613,
38.218514137268066, 19.109257068634033, 9.554628534317017, 4.777314267158508, 2.388657133579254, 1.194328566789627, 0.5971642833948135, 0.298582141697406, 0.149291070848703, 0.0746455354243515, 0.0373227677121757,
];
ZIndexes.base = W.map.olMap.Z_INDEX_BASE.Overlay + 20;
ZIndexes.overlay = W.map.olMap.Z_INDEX_BASE.Overlay + 100;
ZIndexes.popup = W.map.olMap.Z_INDEX_BASE.Overlay + 500;
// adresy WMS služeb * WMS service addresses
var service_wms_PL2023 = {
type: 'WMS',
url: 'https://geoserver.softwel.com.np/geoserver/ows/wms?CQL_FILTER=dyear%3D%272023%27',
attribution: '© DoR / Softwel.com.np',
comment: 'ssrn_PavementLayer2023',
};
var service_wms_softwel = {
type: 'WMS',
url: 'https://geoserver.softwel.com.np/geoserver/ows/wms?',
attribution: '© DoR Nepal/Softwel.com.np',
comment: 'geoserver softwel.com.np',
};
var service_wms_geoportal = {
type: 'WMS',
url: 'https://admin.nationalgeoportal.gov.np/geoserver/wms?',
attribution: '© National Geoportal Nepal',
comment: 'Municipalities names and boundaries',
};
var service_wms_geo_lalitpur = {
type: 'WMS_4326',
url: 'http://localhost:8080/geoserver/geo-lalitpur/wms?',
attribution: '© Geonp.com.np / LMC',
comment: 'Lalitpur House numbers and boundaries',
};
//skupiny vrstev v menu * MapTile service addresses
var service_xyz_livemap = {
type: 'XYZ',
url: ['https://worldtiles1.waze.com/tiles/${z}/${x}/${y}.png?highres=true', 'https://worldtiles2.waze.com/tiles/${z}/${x}/${y}.png?highres=true', 'https://worldtiles3.waze.com/tiles/${z}/${x}/${y}.png?highres=true'],
attribution: "© 2006-2023 Waze Mobile. Všechna práva vyhrazena. Poznámky",
comment: 'Waze Livemapa',
};
var service_xyz_google = {
type: 'XYZ',
url: [
'https://mts0.googleapis.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}',
'https://mts1.googleapis.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}',
'https://mts2.googleapis.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}',
'https://mts3.googleapis.com/vt/lyrs=m&x=${x}&y=${y}&z=${z}',
],
attribution: "Mapová data ©2023 GeoBasis-DE/BKG (©2009),Google Terms and conditions",
comment: 'Google Mapy',
};
var service_xyz_google_terrain = {
type: 'XYZ',
url: [
'https://mts0.googleapis.com/vt/lyrs=p&x=${x}&y=${y}&z=${z}',
'https://mts1.googleapis.com/vt/lyrs=p&x=${x}&y=${y}&z=${z}',
'https://mts2.googleapis.com/vt/lyrs=p&x=${x}&y=${y}&z=${z}',
'https://mts3.googleapis.com/vt/lyrs=p&x=${x}&y=${y}&z=${z}',
],
attribution: "Mapová data ©2023 GeoBasis-DE/BKG (©2009),Google Terms and conditions",
comment: 'Google Terénní Mapy',
};
var service_xyz_google_hybrid = {
type: 'XYZ',
url: [
'https://mts0.googleapis.com/vt/lyrs=y&x=${x}&y=${y}&z=${z}',
'https://mts1.googleapis.com/vt/lyrs=y&x=${x}&y=${y}&z=${z}',
'https://mts2.googleapis.com/vt/lyrs=y&x=${x}&y=${y}&z=${z}',
'https://mts3.googleapis.com/vt/lyrs=y&x=${x}&y=${y}&z=${z}',
],
attribution: "Snímky ©2023 Landsat / Copernicus, Google, GEODIS Brno, Mapová data ©2023 GeoBasis-DE/BKG (©2009),Google Terms and conditions",
comment: 'Google Hybridní Mapy',
};
var service_xyz_google_streetview = {
type: 'XYZ',
url: [
'https://mts0.google.com/mapslt?lyrs=svv&&x=${x}&y=${y}&z=${z}&style=40',
'https://mts1.google.com/mapslt?lyrs=svv&&x=${x}&y=${y}&z=${z}&style=40',
'https://mts2.google.com/mapslt?lyrs=svv&&x=${x}&y=${y}&z=${z}&style=40',
'https://mts3.google.com/mapslt?lyrs=svv&&x=${x}&y=${y}&z=${z}&style=40',
],
attribution: "Google Terms and conditions",
comment: 'Google Streetview',
};
var service_xyz_osm = {
type: 'XYZ',
maxZoom: 20,
url: ['https://tile.openstreetmap.org/${z}/${x}/${y}.png'],
attribution: "© Contributors OpenStreetMap",
comment: 'OpenStreetMaps',
};
var service_xyz_april = {
type: 'XYZ',
maxZoom: 19,
url: [
'https://worldtiles1.waze.com/tiles/${z}/${x}/${y}.png?highres=true',
'https://mts0.googleapis.com/vt/lyrs=m&z=${z}&x=${x}&y=${y}',
'https://mts0.googleapis.com/vt/lyrs=p&z=${z}&x=${x}&y=${y}',
'https://tile.openstreetmap.org/${z}/${x}/${y}.png',
],
attribution: 'mišmaš',
comment: 'mišmaš',
};
//skupiny vrstev v menu * layer groups in the menu
var groupTogglerPlaces = addGroupToggler(true, 'layer-switcher-group_places');
var groupTogglerRoad = addGroupToggler(true, 'layer-switcher-group_road');
// var groupTogglerDisplay = addGroupToggler(true, "layer-switcher-group_display");
var groupTogglerNames = addGroupToggler(false, 'layer-switcher-group_names', 'NP names and addresses');
var groupTogglerBorders = addGroupToggler(false, 'layer-switcher-group_borders', 'NP Borders');
var groupTogglerExternal = addGroupToggler(false, 'layer-switcher-group_external', 'External Maps!!!');
var groupTogglerLalitpur = addGroupToggler(false, 'layer-switcher-group_lalitpur', 'Lalitpur MC HN!');
//vrstvy v menu * layers in the menu
/************************How To add LayerTogglers***************************
WMSLayerTogglers.*(1)* = addLayerToggler(groupTogglerPlaces, "*(2)*", false, [addNewLayer("*(1)*", *(3)*, "*(4)*")]);
INDEX:
*(1)* : LAYER NAME
*(2)* : LAYER DISPLAY NAME AT LIST
*(3)* : SERVICE URL NAME TO PULL DATA FROM
*(4)* : SERVICE URL LAYER NAME TO PULL DATA FROM
****************************************************************************/
//MÍSTA * PLACES
WMSLayerTogglers.wms_rivers = addLayerToggler(groupTogglerPlaces, 'Rivers', false, [addNewLayer('wms_rivers', service_wms_softwel, 'ssrn:ssrn_major_river,npgp:river_nepal')]);
WMSLayerTogglers.wms_airport = addLayerToggler(groupTogglerPlaces, 'Geoportal Airports', false, [addNewLayer('wms_airport', service_wms_geoportal, 'geonode:Transportation', ZIndexes.popup)]);
// Separate education facility layers to avoid duplicate labels
WMSLayerTogglers.wms_prtmp_education = addLayerToggler(groupTogglerPlaces, 'Education Facilities (PRTMP)', false, [addNewLayer('wms_prtmp_education', service_wms_softwel, 'prtmp_01:prtmp_education', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_health = addLayerToggler(groupTogglerPlaces, 'Health Facilities (PRTMP)', false, [addNewLayer('wms_prtmp_health', service_wms_softwel, 'prtmp_01:health_facilities', ZIndexes.popup)]);
WMSLayerTogglers.wms_geoportal_health = addLayerToggler(groupTogglerPlaces, 'Health Facilities (Geoportal)', false, [addNewLayer('wms_geoportal_health', service_wms_geoportal, 'geonode:health_facilities', ZIndexes.popup)]);
WMSLayerTogglers.wms_geoportal_police = addLayerToggler(groupTogglerPlaces, 'Police Units (Geoportal)', false, [addNewLayer('wms_geoportal_police', service_wms_geoportal, 'geonode:All_Nepal_Final_short', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_palika = addLayerToggler(groupTogglerPlaces, 'Palika Centre (PRTMP)', false, [addNewLayer('wms_prtmp_palika', service_wms_softwel, 'prtmp_01:palika_center,prtmp_01:palika_center_name', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_ward = addLayerToggler(groupTogglerPlaces, 'Ward Centre (PRTMP)', false, [addNewLayer('wms_prtmp_ward', service_wms_softwel, 'prtmp_01:prtmp_ward_center', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_tourist = addLayerToggler(groupTogglerPlaces, 'Tourist Attraction', false, [addNewLayer('wms_prtmp_tourist', service_wms_softwel, 'prtmp_01:tourist_attraction', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_customs = addLayerToggler(groupTogglerPlaces, 'Customs Office', false, [addNewLayer('wms_prtmp_customs', service_wms_softwel, 'prtmp_01:trade_transit', ZIndexes.popup)]);
//SILNICE * ROAD
WMSLayerTogglers.wms_PL2023 = addLayerToggler(groupTogglerRoad, 'SSRN Highway 2023', false, [addNewLayer('wms_PL2023', service_wms_PL2023, 'ssrn:ssrn_pavementstatus')]);
WMSLayerTogglers.wms_PRTMP_NH = addLayerToggler(groupTogglerRoad, 'NH 2023 (BSM/PRTMP)', false, [addNewLayer('wms_PRTMP_NH', service_wms_softwel, 'prtmp_01:road_network,prtmp_01:road_network_name', "road_class='NH';road_class='NH'")]);
WMSLayerTogglers.wms_PRTMP_PH = addLayerToggler(groupTogglerRoad, 'PH 2023 (BSM/PRTMP)', false, [addNewLayer('wms_PRTMP_PH', service_wms_softwel, 'prtmp_01:road_network,prtmp_01:road_network_name', "road_class='PH';road_class='PH'")]);
WMSLayerTogglers.wms_PRTMP_PR = addLayerToggler(groupTogglerRoad, 'PR 2023 (BSM/PRTMP)', false, [addNewLayer('wms_PRTMP_PR', service_wms_softwel, 'prtmp_01:road_network,prtmp_01:road_network_name', "road_class='PR';road_class='PR'")]);
WMSLayerTogglers.wms_BSM_Bridge = addLayerToggler(groupTogglerRoad, 'Bridges (BSM)', false, [addNewLayer('wms_BSM_Bridge', service_wms_softwel, 'bsm:bsm_nc_primary_detail,bsm:nc_primary_detail_code,bsm:bsm_bi_primary_detail', ZIndexes.popup)]);
WMSLayerTogglers.wms_prtmp_bridge = addLayerToggler(groupTogglerRoad, 'Bridges (PRTMP)', false, [addNewLayer('wms_prtmp_bridge', service_wms_softwel, 'prtmp_01:bridge_inventory_local,prtmp_01:local_bridge,prtmp_01:major_bridge', ZIndexes.popup)]);
//ZOBRAZENÍ * DISPLAY
// WMSLayerTogglers.wms_orto = addLayerToggler(groupTogglerDisplay, "Ortofoto ČUZK", true, [addNewLayer("wms_orto", service_wms_orto, "GR_ORTFOTORGB", ZIndexes.base)]);
//ČÚZK NÁZVY A ADRESY * ČÚZK NAMES AND ADDRESSES
WMSLayerTogglers.wms_mun_name = addLayerToggler(groupTogglerNames, 'BSM Municipality Names', false, [addNewLayer('wms_mun_name', service_wms_softwel, 'bsm:bsm_localbodies_label')]);
WMSLayerTogglers.wms_junction_name = addLayerToggler(groupTogglerNames, 'SSRN Junction Names', false, [addNewLayer('wms_junction_name', service_wms_softwel, 'ssrn:ssrn_junction_name')]);
WMSLayerTogglers.wms_lalitpur_metric_house = addLayerToggler(groupTogglerNames, 'Lalitpur Metric House', false, [
addNewLayer(
'wms_lalitpur_metric_house',
service_wms_geo_lalitpur,
'geo-lalitpur:lmc_w-01_metric_house,geo-lalitpur:lmc_w-02_metric_house,geo-lalitpur:lmc_w-03_metric_house,geo-lalitpur:lmc_w-04_metric_house,geo-lalitpur:lmc_w-05_metric_house,geo-lalitpur:lmc_w-06_metric_house,geo-lalitpur:lmc_w-07_metric_house,geo-lalitpur:lmc_w-08_metric_house,geo-lalitpur:lmc_w-09_metric_house,geo-lalitpur:lmc_w-10_metric_house,geo-lalitpur:lmc_w-11_metric_house,geo-lalitpur:lmc_w-12_metric_house,geo-lalitpur:lmc_w-13_metric_house,geo-lalitpur:lmc_w-14_metric_house,geo-lalitpur:lmc_w-15_metric_house,geo-lalitpur:lmc_w-16_metric_house,geo-lalitpur:lmc_w-17_metric_house,geo-lalitpur:lmc_w-18_metric_house,geo-lalitpur:lmc_w-19_metric_house,geo-lalitpur:lmc_w-20_metric_house,geo-lalitpur:lmc_w-22_metric_house,geo-lalitpur:lmc_w-23_metric_house,geo-lalitpur:lmc_w-24_metric_house,geo-lalitpur:lmc_w-25_metric_house,geo-lalitpur:lmc_w-26_metric_house,geo-lalitpur:lmc_w-27_metric_house,geo-lalitpur:lmc_w-28_metric_house,geo-lalitpur:lmc_w-29_metric_house'
),
]);
//ČÚZK HRANICE * BORDER BOARD
WMSLayerTogglers.wms_geonational = addLayerToggler(groupTogglerBorders, 'Geoportal National Border', false, [addNewLayer('wms_geonational', service_wms_geoportal, 'geonode:nepal')]);
WMSLayerTogglers.wms_national = addLayerToggler(groupTogglerBorders, 'SSRN National Border', false, [addNewLayer('wms_national', service_wms_softwel, 'ssrn:ssrn_national_boundary_line')]);
WMSLayerTogglers.wms_geoprovince = addLayerToggler(groupTogglerBorders, 'Geoportal Province Border', false, [addNewLayer('wms_geoprovince', service_wms_geoportal, 'geonode:province')]);
WMSLayerTogglers.wms_province = addLayerToggler(groupTogglerBorders, 'SSRN Province Border', false, [addNewLayer('wms_province', service_wms_softwel, 'ssrn:ssrn_province_line')]);
WMSLayerTogglers.wms_geodistrict = addLayerToggler(groupTogglerBorders, 'Geoportal District Border', false, [addNewLayer('wms_geodistrict', service_wms_geoportal, 'geonode:districts')]);
WMSLayerTogglers.wms_district = addLayerToggler(groupTogglerBorders, 'SSRN District Border', false, [addNewLayer('wms_district', service_wms_softwel, 'ssrn:ssrn_district_boundary_line')]);
WMSLayerTogglers.wms_geomunicipality = addLayerToggler(groupTogglerBorders, 'Geoportal Municipality Border', false, [addNewLayer('wms_geomunicipality', service_wms_geoportal, 'geonode:NepalLocalUnits0')]);
WMSLayerTogglers.wms_municipality = addLayerToggler(groupTogglerBorders, 'BSM Municipality Border', false, [addNewLayer('wms_municipality', service_wms_softwel, 'bsm:bsm_localbodies_line')]);
WMSLayerTogglers.wms_lalitpur_boundary = addLayerToggler(groupTogglerBorders, 'Lalitpur Ward Boundary', false, [
addNewLayer(
'wms_lalitpur_boundary',
service_wms_geo_lalitpur,
'geo-lalitpur:lmc_w-01_boundary,geo-lalitpur:lmc_w-02_boundary,geo-lalitpur:lmc_w-03_boundary,geo-lalitpur:lmc_w-04_boundary,geo-lalitpur:lmc_w-05_boundary,geo-lalitpur:lmc_w-06_boundary,geo-lalitpur:lmc_w-07_boundary,geo-lalitpur:lmc_w-08_boundary,geo-lalitpur:lmc_w-09_boundary,geo-lalitpur:lmc_w-10_boundary,geo-lalitpur:lmc_w-11_boundary,geo-lalitpur:lmc_w-12_boundary,geo-lalitpur:lmc_w-13_boundary,geo-lalitpur:lmc_w-14_boundary,geo-lalitpur:lmc_w-15_boundary,geo-lalitpur:lmc_w-16_boundary,geo-lalitpur:lmc_w-17_boundary,geo-lalitpur:lmc_w-18_boundary,geo-lalitpur:lmc_w-19_boundary,geo-lalitpur:lmc_w-20_boundary,geo-lalitpur:lmc_w-22_boundary,geo-lalitpur:lmc_w-23_boundary,geo-lalitpur:lmc_w-24_boundary,geo-lalitpur:lmc_w-25_boundary,geo-lalitpur:lmc_w-26_boundary,geo-lalitpur:lmc_w-27_boundary,geo-lalitpur:lmc_w-28_boundary,geo-lalitpur:lmc_w-29_boundary'
),
]);
//EXTERNÍ MAPY * EXTERNAL MAPS
WMSLayerTogglers.xyz_livemap = addLayerToggler(groupTogglerExternal, 'Waze LiveMap', false, [addNewLayer('xyz_livemap', service_xyz_livemap)]);
WMSLayerTogglers.xyz_google = addLayerToggler(groupTogglerExternal, 'Google Maps', false, [addNewLayer('xyz_google', service_xyz_google)]);
WMSLayerTogglers.xyz_google_terrain = addLayerToggler(groupTogglerExternal, 'Google Terrain Maps', false, [addNewLayer('xyz_google_terrain', service_xyz_google_terrain)]);
WMSLayerTogglers.xyz_google_hybrid = addLayerToggler(groupTogglerExternal, 'Google Hybrid Maps', false, [addNewLayer('xyz_google_hybrid', service_xyz_google_hybrid)]);
WMSLayerTogglers.xyz_google_streetview = addLayerToggler(groupTogglerExternal, 'Google StreetView', false, [addNewLayer('xyz_google_streetview', service_xyz_google_streetview, null, ZIndexes.popup)]);
WMSLayerTogglers.xyz_osm = addLayerToggler(groupTogglerExternal, 'OpenStreetMaps', false, [addNewLayer('xyz_osm', service_xyz_osm)]);
WMSLayerTogglers.xyz_april = addLayerToggler(groupTogglerExternal, 'Apríl !!!', false, [addNewLayer('xyz_april', service_xyz_april)]);
//LALITPUR METRO CITY METRIC HOUSE NUMBERING
WMSLayerTogglers.wms_lmc_ward1 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 1', false, [addNewLayer('wms_lmc_ward1', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-01_metric_house,geo-lalitpur:lmc_w-01_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward2 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 2', false, [addNewLayer('wms_lmc_ward2', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-02_metric_house,geo-lalitpur:lmc_w-02_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward3 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 3', false, [addNewLayer('wms_lmc_ward3', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-03_metric_house,geo-lalitpur:lmc_w-03_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward4 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 4', false, [addNewLayer('wms_lmc_ward4', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-04_metric_house,geo-lalitpur:lmc_w-04_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward5 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 5', false, [addNewLayer('wms_lmc_ward5', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-05_metric_house,geo-lalitpur:lmc_w-05_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward6 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 6', false, [addNewLayer('wms_lmc_ward6', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-06_metric_house,geo-lalitpur:lmc_w-06_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward7 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 7', false, [addNewLayer('wms_lmc_ward7', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-07_metric_house,geo-lalitpur:lmc_w-07_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward8 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 8', false, [addNewLayer('wms_lmc_ward8', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-08_metric_house,geo-lalitpur:lmc_w-08_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward9 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 9', false, [addNewLayer('wms_lmc_ward9', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-09_metric_house,geo-lalitpur:lmc_w-09_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward10 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 10', false, [addNewLayer('wms_lmc_ward10', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-10_metric_house,geo-lalitpur:lmc_w-10_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward11 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 11', false, [addNewLayer('wms_lmc_ward11', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-11_metric_house,geo-lalitpur:lmc_w-11_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward12 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 12', false, [addNewLayer('wms_lmc_ward12', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-12_metric_house,geo-lalitpur:lmc_w-12_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward13 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 13', false, [addNewLayer('wms_lmc_ward13', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-13_metric_house,geo-lalitpur:lmc_w-13_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward14 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 14', false, [addNewLayer('wms_lmc_ward14', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-14_metric_house,geo-lalitpur:lmc_w-14_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward15 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 15', false, [addNewLayer('wms_lmc_ward15', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-15_metric_house,geo-lalitpur:lmc_w-15_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward16 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 16', false, [addNewLayer('wms_lmc_ward16', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-16_metric_house,geo-lalitpur:lmc_w-16_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward17 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 17', false, [addNewLayer('wms_lmc_ward17', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-17_metric_house,geo-lalitpur:lmc_w-17_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward18 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 18', false, [addNewLayer('wms_lmc_ward18', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-18_metric_house,geo-lalitpur:lmc_w-18_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward19 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 19', false, [addNewLayer('wms_lmc_ward19', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-19_metric_house,geo-lalitpur:lmc_w-19_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward20 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 20', false, [addNewLayer('wms_lmc_ward20', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-20_metric_house,geo-lalitpur:lmc_w-20_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward21 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 21', false, [addNewLayer('wms_lmc_ward21', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-21_metric_house,geo-lalitpur:lmc_w-21_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward22 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 22', false, [addNewLayer('wms_lmc_ward22', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-22_metric_house,geo-lalitpur:lmc_w-22_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward23 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 23', false, [addNewLayer('wms_lmc_ward23', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-23_metric_house,geo-lalitpur:lmc_w-23_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward24 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 24', false, [addNewLayer('wms_lmc_ward24', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-24_metric_house,geo-lalitpur:lmc_w-24_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward25 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 25', false, [addNewLayer('wms_lmc_ward25', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-25_metric_house,geo-lalitpur:lmc_w-25_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward26 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 26', false, [addNewLayer('wms_lmc_ward26', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-26_metric_house,geo-lalitpur:lmc_w-26_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward27 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 27', false, [addNewLayer('wms_lmc_ward27', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-27_metric_house,geo-lalitpur:lmc_w-27_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward28 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 28', false, [addNewLayer('wms_lmc_ward28', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-28_metric_house,geo-lalitpur:lmc_w-28_boundary',ZIndexes.base)]);
WMSLayerTogglers.wms_lmc_ward29 = addLayerToggler(groupTogglerLalitpur, 'LMC Ward 29', false, [addNewLayer('wms_lmc_ward29', service_wms_geo_lalitpur, 'geo-lalitpur:lmc_w-29_metric_house,geo-lalitpur:lmc_w-29_boundary',ZIndexes.base)]);
// --- Layer toggler state persistence ---
function saveLayerTogglerStates() {
if (!localStorage) return;
const state = {};
for (const key in WMSLayerTogglers) {
const togglerId = WMSLayerTogglers[key].htmlItem;
const toggler = document.getElementById(togglerId);
if (toggler) state[key] = toggler.checked;
}
localStorage.WMSLayers = JSON.stringify(state);
}
function restoreLayerTogglerStates() {
if (!localStorage.WMSLayers) return;
const state = JSON.parse(localStorage.WMSLayers);
for (const key in state) {
if (WMSLayerTogglers[key]) {
const togglerId = WMSLayerTogglers[key].htmlItem;
const toggler = document.getElementById(togglerId);
if (toggler && toggler.checked !== state[key]) {
toggler.checked = state[key];
toggler.dispatchEvent(new Event('change', { bubbles: true }));
}
}
}
}
// Attach change listeners to save state on toggle
for (const key in WMSLayerTogglers) {
const togglerId = WMSLayerTogglers[key].htmlItem;
const toggler = document.getElementById(togglerId);
if (toggler) {
toggler.addEventListener('change', saveLayerTogglerStates);
}
}
// Restore state after togglers are created
restoreLayerTogglerStates();
/********************* start of popup code ***************************/
// --- WMS GetFeatureInfo popup for SSRN Pavement Layer ---
const map = W.map.olMap;
// Helper: get all visible supported WMS layers for popup
function getAllVisibleWMSLayerInfo() {
const supported = [
{ key: 'wms_rivers', service: service_wms_softwel, queryLayer: 'ssrn:ssrn_major_river,npgp:river_nepal', displayName: 'Rivers', formatFn: (feature) => formatFeatureInfo('RIVER', feature) },
{ key: 'wms_prtmp_education', service: service_wms_softwel, queryLayer: 'prtmp_01:prtmp_education', displayName: 'Education Facilities (PRTMP)', formatFn: (feature) => formatFeatureInfo('EDUCATION', feature) },
{ key: 'wms_prtmp_health', service: service_wms_softwel, queryLayer: 'prtmp_01:health_facilities', displayName: 'Health Facilities (PRTMP)', formatFn: (feature) => formatFeatureInfo('HEALTH', feature) },
{ key: 'wms_geoportal_health', service: service_wms_geoportal, queryLayer: 'geonode:health_facilities', displayName: 'Health Facilities (Geoportal)', formatFn: (feature) => formatFeatureInfo('GEO_HEALTH', feature) },
{ key: 'wms_geoportal_police', service: service_wms_geoportal, queryLayer: 'geonode:All_Nepal_Final_short', displayName: 'Police Units (Geoportal)', formatFn: (feature) => formatFeatureInfo('GEO_POLICE', feature) },
{ key: 'wms_prtmp_palika', service: service_wms_softwel, queryLayer: 'prtmp_01:palika_center', displayName: 'Palika Centre (PRTMP)', formatFn: (feature) => formatFeatureInfo('PALIKA', feature) },
{ key: 'wms_prtmp_ward', service: service_wms_softwel, queryLayer: 'prtmp_01:prtmp_ward_center', displayName: 'Ward Centre (PRTMP)', formatFn: (feature) => formatFeatureInfo('WARD', feature) },
{ key: 'wms_prtmp_tourist', service: service_wms_softwel, queryLayer: 'prtmp_01:tourist_attraction', displayName: 'Tourist Attraction', formatFn: (feature) => formatFeatureInfo('TOURIST', feature) },
{ key: 'wms_prtmp_customs', service: service_wms_softwel, queryLayer: 'prtmp_01:trade_transit', displayName: 'Customs Office', formatFn: (feature) => formatFeatureInfo('CUSTOMS', feature) },
{ key: 'wms_PL2023', service: service_wms_PL2023, queryLayer: 'ssrn:ssrn_pavementstatus', displayName: 'SSRN Highway 2023', formatFn: (feature) => formatFeatureInfo('SSRN', feature) },
{ key: 'wms_PRTMP_NH', service: service_wms_softwel, queryLayer: 'prtmp_01:road_network', displayName: 'NH 2023 (BSM/PRTMP)', formatFn: (feature) => formatFeatureInfo('BSM', feature), cqlFilter: "road_class='NH'" },
{ key: 'wms_PRTMP_PH', service: service_wms_softwel, queryLayer: 'prtmp_01:road_network', displayName: 'PH 2023 (BSM/PRTMP)', formatFn: (feature) => formatFeatureInfo('BSM', feature), cqlFilter: "road_class='PH'" },
{ key: 'wms_PRTMP_PR', service: service_wms_softwel, queryLayer: 'prtmp_01:road_network', displayName: 'PR 2023 (BSM/PRTMP)', formatFn: (feature) => formatFeatureInfo('BSM', feature), cqlFilter: "road_class='PR'" },
{
key: 'wms_BSM_Bridge',
service: service_wms_softwel,
queryLayer: 'bsm:bsm_nc_primary_detail,bsm:nc_primary_detail_code,bsm:bsm_bi_primary_detail',
displayName: 'Bridges (BSM)',
formatFn: (feature) => formatFeatureInfo('BRIDGE', feature),
},
{
key: 'wms_prtmp_bridge',
service: service_wms_softwel,
queryLayer: 'prtmp_01:bridge_inventory_local,prtmp_01:local_bridge,prtmp_01:major_bridge',
displayName: 'Bridges (PRTMP)',
formatFn: (feature) => formatFeatureInfo('BRIDGE', feature),
},
];
const visible = [];
for (const s of supported) {
const toggler = WMSLayerTogglers[s.key];
if (!toggler) {
continue;
}
const layer = toggler.layerArray && toggler.layerArray[0] && toggler.layerArray[0].layer;
if (layer && layer.getVisibility()) {
visible.push({ layer, service: s.service, queryLayer: s.queryLayer, formatFn: s.formatFn, key: s.key, displayName: s.displayName, cqlFilter: s.cqlFilter });
}
}
return visible;
}
// Helper: build GetFeatureInfo URL for any supported WMS layer
function buildGetFeatureInfoUrl(service, queryLayer, evt, cqlFilter = null) {
const wmsUrl = service.url;
const bbox = map.getExtent();
const width = map.size.w;
const height = map.size.h;
const x = Math.round(evt.xy.x);
const y = Math.round(evt.xy.y);
// Handle CQL filters - priority: parameter > service URL
let cql = '';
if (cqlFilter) {
cql = 'CQL_FILTER=' + encodeURIComponent(cqlFilter);
console.log('[WMS DEBUG] Using layer-specific CQL filter for GetFeatureInfo:', cqlFilter);
} else if (wmsUrl.includes('CQL_FILTER=')) {
const match = wmsUrl.match(/CQL_FILTER=([^&]*)/);
if (match) {
cql = 'CQL_FILTER=' + match[1];
console.log('[WMS DEBUG] Using service URL CQL filter for GetFeatureInfo:', decodeURIComponent(match[1]));
}
}
// Determine CRS: use map.projection or fallback to EPSG:3857
let crs = 'EPSG:3857';
if (map.projection && (map.projection === 'EPSG:4326' || map.projection === 'EPSG:3857')) {
crs = map.projection;
}
// Optionally add FEATURE_COUNT if present in service config
let featureCount = '';
if (service.featureCount) {
featureCount = 'FEATURE_COUNT=' + service.featureCount;
}
const params = [
'SERVICE=WMS',
'VERSION=1.3.0',
'REQUEST=GetFeatureInfo',
'FORMAT=image/png',
'TRANSPARENT=true',
'QUERY_LAYERS=' + encodeURIComponent(queryLayer),
'LAYERS=' + encodeURIComponent(queryLayer),
'INFO_FORMAT=application/json',
cql,
'STYLES=',
'TILED=true',
'buffer=10',
'CRS=' + crs,
'WIDTH=' + width,
'HEIGHT=' + height,
'BBOX=' + bbox.left + ',' + bbox.bottom + ',' + bbox.right + ',' + bbox.top,
'I=' + x,
'J=' + y,
featureCount,
].filter(Boolean);
const finalUrl = wmsUrl.split('?')[0] + '?' + params.join('&');
if (cqlFilter) {
console.log('[WMS DEBUG] GetFeatureInfo URL with CQL filter:', finalUrl);
}
return finalUrl;
}
// Helper: show popup at pixel position with content (custom HTML popup)
function showWMSPopupAtPixel(pixel, html) {
let popup = document.getElementById('wms-info-popup');
if (!popup) {
popup = document.createElement('div');
popup.id = 'wms-info-popup';
popup.style.position = 'absolute';
popup.style.zIndex = 9999;
popup.style.background = 'white';
popup.style.border = '2px solid #333';
popup.style.borderRadius = '8px';
popup.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)';
popup.style.padding = '10px 14px 10px 10px';
popup.style.minWidth = '220px';
popup.style.maxWidth = '350px';
popup.style.pointerEvents = 'auto';
popup.style.fontSize = '11px';
popup.style.fontFamily = 'inherit';
popup.style.display = 'block';
popup.innerHTML = '';
document.body.appendChild(popup);
}
// Add close button and table styling
popup.innerHTML = `
×
${html}
`;
// Position popup (pixel is {x, y} relative to map viewport)
const mapDiv = map.div;
const rect = mapDiv.getBoundingClientRect();
popup.style.left = rect.left + pixel.x + 10 + 'px';
popup.style.top = rect.top + pixel.y - 10 + 'px';
popup.style.display = 'block';
// Close handler
document.getElementById('wms-info-popup-close').onclick = function (e) {
e.preventDefault();
popup.style.display = 'none';
};
}
// Helper: show popup at pixel position with content (custom HTML popup), unique per layer
function showWMSPopupAtPixelForLayer(pixel, html, layerKey) {
let popupId = 'wms-info-popup-' + layerKey;
let popup = document.getElementById(popupId);
if (!popup) {
popup = document.createElement('div');
popup.id = popupId;
popup.style.position = 'absolute';
popup.style.zIndex = 9999;
popup.style.background = 'white';
popup.style.border = '2px solid #333';
popup.style.borderRadius = '8px';
popup.style.boxShadow = '0 2px 8px rgba(0,0,0,0.3)';
popup.style.padding = '10px 14px 10px 10px';
popup.style.minWidth = '220px';
popup.style.maxWidth = '350px';
popup.style.pointerEvents = 'auto';
popup.style.fontSize = '11px';
popup.style.fontFamily = 'inherit';
popup.style.display = 'block';
popup.innerHTML = '';
document.body.appendChild(popup);
}
// Add close button and table styling
popup.innerHTML = `
×
${html}
`;
// Position popup (pixel is {x, y} relative to map viewport)
const mapDiv = map.div;
const rect = mapDiv.getBoundingClientRect();
// Offset each popup horizontally so they don't overlap
let offsetX = 10 + 260 * ['wms_PL2023', 'wms_PRTMP_PH', 'wms_PRTMP_PR'].indexOf(layerKey);
popup.style.left = rect.left + pixel.x + offsetX + 'px';
popup.style.top = rect.top + pixel.y - 10 + 'px';
popup.style.display = 'block';
// Close handler
document.getElementById(`${popupId}-close`).onclick = function (e) {
e.preventDefault();
popup.style.display = 'none';
};
}
// Helper: format feature info for popup based on type
function formatFeatureInfo(type, feature) {
// Define field sets and titles for each type
const configs = {
SSRN: {
title: (feature) => feature.layerName || 'Strategic Road Network',
fields: [
['road_code', 'Road Code'],
['link_name', 'Link Name'],
['road_name', 'Road Name'],
['from_ch', 'From chainage'],
['to_ch', 'To chainage'],
['pave_type', 'Pavement type'],
['last_resurface', 'Last Resurface Year'],
['pave_width', 'Pave Width'],
['dyear', 'Year'],
['add_date', 'Added'],
],
},
BSM: {
title: (feature) => feature.layerName || 'BSM Province Road Info',
fields: [
['road_code', 'Road Code'],
['road_class', 'Road Class'],
['road_name', 'Road Name'],
['pcode', 'Province'],
['start_ch', 'From chainage'],
['end_ch', 'To chainage'],
['dyear', 'Year'],
['add_date', 'Added'],
],
},
EDUCATION: {
title: (feature) => feature.layerName || 'Education Facilities',
fields: [
['name', 'School Name'],
['loc_bodies', 'Mun Name'],
['district', 'District'],
],
},
HEALTH: {
title: (feature) => feature.layerName || 'Health Facilities',
fields: [
['hf_name', 'Name'],
['category', 'Category'],
['loc_bodies', 'Mun Name'],
['ward', 'Ward'],
['district', 'District'],
['province', 'Province'],
],
},
GEO_HEALTH: {
title: (feature) => feature.layerName || 'Health Facilities',
fields: [
['health_fac', 'Name'],
['Categorise', 'Category'],
['status_lev', 'Status Level'],
['local_gove', 'Mun Name'],
['District', 'District'],
['Province', 'Province'],
],
},
GEO_POLICE: {
title: (feature) => feature.layerName || 'Police Units',
fields: [
['EngName', 'Name'],
['Nepali_Nam', 'Nep Name'],
['dis', 'District'],
['Provinces', 'Province'],
],
},
RIVER: {
title: (feature) => feature.layerName || 'River Features',
fields: [['riv_name', 'Name']],
},
PALIKA: {
title: (feature) => feature.layerName || 'Palika Centre',
fields: [
['loc_bod', 'Name Eng'],
['dist_name', 'District Eng'],
['province', 'Province'],
['palika_nep', 'Palika NP'],
['dist_nep', 'District NP'],
],
},
WARD: {
title: (feature) => feature.layerName || 'Ward Centre',
fields: [
['pcode', 'Province'],
['loc_name', 'Name'],
['type_gn', 'Type'],
['ward_no', 'Ward No'],
],
},
TOURIST: {
title: (feature) => feature.layerName || 'Tourist Attraction',
fields: [
['pcode', 'Province'],
['name', 'Name'],
['district', 'District'],
],
},
CUSTOMS: {
title: (feature) => feature.layerName || 'Customs Office',
fields: [
['pcode', 'Province'],
['name', 'Name'],
['district', 'District'],
],
},
BRIDGE: {
title: (feature) => feature.layerName || 'Bridge',
fields: [
['pcode', 'Province'],
[['name', 'bridge_name'], 'Bridge Name'], // Array of fallback field names
[['bridge_id', 'bridge_no', 'new_bridge_no'], 'Bridge ID'], // Array of fallback field names
['bridge_length', 'Bridge Length'],
[['river', 'river_name'], 'River'], // Array of fallback field names
['road', 'Road Name'], // Array of fallback field names
['district', 'District'],
['updated_date', 'Updated Date'],
],
},
};
const config = configs[type];
if (!config) return '
| ${layerTitle} | |
|---|---|
| ${label}: | ${value} |