Merge pull request #33848 from 0MUHAMMEDIRFAN/geolocation-modify

feat: map layers in geolocation
This commit is contained in:
Ejaaz Khan 2025-09-04 12:47:49 +05:30 committed by GitHub
commit e3075bd0d6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 168 additions and 8 deletions

View file

@ -47,6 +47,7 @@ frappe.ui.form.ControlGeolocation = class ControlGeolocation extends frappe.ui.f
if (!this.map) {
this.customize_draw_controls();
this.bind_leaflet_map();
this.bind_leaflet_layers_control();
}
if (this.disabled) {
this.map.dragging.disable();
@ -156,13 +157,45 @@ frappe.ui.form.ControlGeolocation = class ControlGeolocation extends frappe.ui.f
this.map = L.map(this.map_id);
this.map.setView(frappe.utils.map_defaults.center, frappe.utils.map_defaults.zoom);
L.tileLayer(frappe.utils.map_defaults.tiles, frappe.utils.map_defaults.options).addTo(
this.map
this.streetLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.default_tile.url,
frappe.utils.map_defaults.tiles.default_tile.options
);
this.satelliteLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.satellite_tile.url,
frappe.utils.map_defaults.tiles.satellite_tile.options
);
this.labelsLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.labels_tail.url,
frappe.utils.map_defaults.tiles.labels_tail.options
);
this.terrainLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.terrain_lines_tail.url,
frappe.utils.map_defaults.tiles.terrain_lines_tail.options
);
this.streetLayer.addTo(this.map);
this.editableLayers = new L.FeatureGroup();
}
bind_leaflet_layers_control() {
// Add layers control for switching between map types
// Define base and overlay layers as properties of the class instance for access in other methods
const baseLayers = {
Default: this.streetLayer,
Satellite: this.satelliteLayer,
};
const overlays = {
Labels: this.labelsLayer,
Terrain: this.terrainLayer,
};
L.control.layers(baseLayers, overlays).addTo(this.map);
this.display_leaflet_overlays_control("none");
}
bind_leaflet_locate_control() {
// To request location update and set location, sets current geolocation on load
this.locate_control = L.control.locate({ position: "topright" });
@ -214,6 +247,17 @@ frappe.ui.form.ControlGeolocation = class ControlGeolocation extends frappe.ui.f
});
}
display_leaflet_overlays_control(display = "") {
const layerControlContainer = document.querySelector(".leaflet-control-layers-overlays");
const separator = document.querySelector(".leaflet-control-layers-separator");
if (layerControlContainer) {
layerControlContainer.style.display = display;
}
if (separator) {
separator.style.display = display;
}
}
bind_leaflet_event_listeners() {
this.bound_event_listeners = true;
this.map.on("draw:created", (e) => {
@ -231,6 +275,27 @@ frappe.ui.form.ControlGeolocation = class ControlGeolocation extends frappe.ui.f
this.editableLayers.removeLayer(layer);
this.set_value(JSON.stringify(this.editableLayers.toGeoJSON()));
});
// Remove overlays and overlays options when selecting the default view
this.map.on("baselayerchange", (e) => {
if (e.name === "Satellite") {
// Show overlays options and separator only in Satellite view
this.display_leaflet_overlays_control();
} else {
// Hide overlays options and separator in other views
this.display_leaflet_overlays_control("none");
// Remove all overlays
Object.values(this.map._layers).forEach((layer) => {
if (
layer instanceof L.TileLayer &&
(layer._url === frappe.utils.map_defaults.tiles.labels_tail.url ||
layer._url === frappe.utils.map_defaults.tiles.terrain_lines_tail.url)
) {
this.map.removeLayer(layer);
}
});
}
});
}
add_non_group_layers(source_layer, target_group) {

View file

@ -1203,10 +1203,34 @@ Object.assign(frappe.utils, {
map_defaults: {
center: [19.08, 72.8961],
zoom: 13,
tiles: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
options: {
attribution:
'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
tiles: {
default_tile: {
url: "https://tile.openstreetmap.org/{z}/{x}/{y}.png",
options: {
attribution:
'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors',
},
},
satellite_tile: {
url: "https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}",
options: {
attribution: "© Esri © OpenStreetMap Contributors",
},
},
labels_tail: {
url: "https://tiles.stadiamaps.com/tiles/stamen_toner_labels/{z}/{x}/{y}{r}.png",
options: {
attribution:
'&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://www.stamen.com/" target="_blank">Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a>',
},
},
terrain_lines_tail: {
url: "https://tiles.stadiamaps.com/tiles/stamen_terrain_lines/{z}/{x}/{y}{r}.png",
options: {
attribution:
'&copy; <a href="https://www.stadiamaps.com/" target="_blank">Stadia Maps</a> &copy; <a href="https://www.stamen.com/" target="_blank">Stamen Design</a> &copy; <a href="https://openmaptiles.org/" target="_blank">OpenMapTiles</a>',
},
},
},
image_path: "/assets/frappe/images/leaflet/",
},

View file

@ -43,12 +43,31 @@ frappe.views.MapView = class MapView extends frappe.views.ListView {
frappe.utils.map_defaults.zoom
);
L.tileLayer(frappe.utils.map_defaults.tiles, frappe.utils.map_defaults.options).addTo(
this.map
this.streetLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.default_tile.url,
frappe.utils.map_defaults.tiles.default_tile.options
);
this.satelliteLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.satellite_tile.url,
frappe.utils.map_defaults.tiles.satellite_tile.options
);
this.labelsLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.labels_tail.url,
frappe.utils.map_defaults.tiles.labels_tail.options
);
this.terrainLayer = L.tileLayer(
frappe.utils.map_defaults.tiles.terrain_lines_tail.url,
frappe.utils.map_defaults.tiles.terrain_lines_tail.options
);
this.streetLayer.addTo(this.map);
this.bind_leaflet_layers_control();
this.bind_leaflet_locate_control();
L.control.scale().addTo(this.map);
if (!this.bound_event_listeners) {
this.bind_leaflet_event_listeners();
}
}
render() {
@ -140,9 +159,61 @@ frappe.views.MapView = class MapView extends frappe.views.ListView {
}
}
bind_leaflet_layers_control() {
// Add layers control for switching between map types
// Define base and overlay layers as properties of the class instance for access in other methods
const baseLayers = {
Default: this.streetLayer,
Satellite: this.satelliteLayer,
};
const overlays = {
Labels: this.labelsLayer,
Terrain: this.terrainLayer,
};
L.control.layers(baseLayers, overlays).addTo(this.map);
this.display_leaflet_overlays_control("none");
}
bind_leaflet_locate_control() {
// To request location update and set location, sets current geolocation on load
this.locate_control = L.control.locate({ position: "topright" });
this.locate_control.addTo(this.map);
}
display_leaflet_overlays_control(display = "") {
const layerControlContainer = document.querySelector(".leaflet-control-layers-overlays");
const separator = document.querySelector(".leaflet-control-layers-separator");
if (layerControlContainer) {
layerControlContainer.style.display = display;
}
if (separator) {
separator.style.display = display;
}
}
bind_leaflet_event_listeners() {
this.bound_event_listeners = true;
// Remove overlays and overlays options when selecting the default view
this.map.on("baselayerchange", (e) => {
if (e.name === "Satellite") {
// Show overlays options and separator only in Satellite view
this.display_leaflet_overlays_control();
} else {
// Hide overlays options and separator in other views
this.display_leaflet_overlays_control("none");
// Remove all overlays
Object.values(this.map._layers).forEach((layer) => {
if (
layer instanceof L.TileLayer &&
(layer._url === frappe.utils.map_defaults.tiles.labels_tail.url ||
layer._url === frappe.utils.map_defaults.tiles.terrain_lines_tail.url)
) {
this.map.removeLayer(layer);
}
});
}
});
}
};