How to: Customize the Geolocation (map) control

When creating or customizing a DocType, we can add a “Geolocation” field.

This shows a map in the form view. Users can draw on it and set markers.

By default, it shows a street map centered on Mumbai. This is not configurable via the GUI yet. But, using a custom app, we can change the map type, start location, zoom level, etc.

Note: this guide is for v13

Start by creating a file $MY_APP/$MY_APP/public/js/map_defaults.js. In your $MY_APP/$MY_APP/hooks.py, add the JS file into the app_include_js hook:

app_include_js = [
    "/assets/$MY_APP/js/map_defaults.js"
    # ...
]

Now, frappe will load this file for all desk views (i.e. for logged in system users).

In map_defaults.js, we add the following lines:

// Make sure we have a dictionary to add our custom settings
const map_settings = frappe.provide("frappe.utils.map_defaults");

// Center and zoomlevel can be copied from the URL of
// the map view at openstreetmap.org.

// New default location (middle of germany).
map_settings.center = [51.57, 9.866];
// new zoomlevel: see the whole country, not just a single city
map_settings.zoom = 6;

// Use a different map: satellite instead of streets
// Examples can be found at https://leaflet-extras.github.io/leaflet-providers/preview/
map_settings.tiles =
	"https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}";
map_settings.attribution =
	"Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community";

Restart your bench and reload your browser window. Now you should see the customized map (yes, that’s what Germany looks like from above :laughing: ):

Note that the above applies to all map views on this system.

14 Likes

Thanks! Is it possible to apply these while being hosted on Frappe Cloud?
If so, how?

Not working,

This is aimed at custom apps. On Frappe Cloud, it can probably be done via Client Script, but only for a specific DocType, not for the entire system.

Would be more interesting if you told us the details… what exactly did you do (step-by-step)? Which version of Frappe are you using?

Yeah, I added geolocation field on Lead doctype, but when i create new Lead the default view of the Geolocation field is set to Mumbai, I want to set the view on London, I am using Frappe Framework: v13.47.0 (HEAD) and ERPNext: v13.43.1 (HEAD), As told i try to overright the default view but it not works.

is it possible to customize the location pin? I want to have different colors per different document status, as well as the text attached on the pin

I don’t know how yet, but I’ll have to figure it out soon. I think leaflet does support this, in principle.

Hi all,

I use the following to access the leaflet map object and add different types of information to the map or set specific coordinates, where “geo” is a variable that holds a geoJSON object. You should be able to add any object that is supported by leaflet to the “map” object, and you should also be able to change any other setting in the map object:

let map = frm.get_field('map').map
map.setZoom(1);

L.geoJSON(geo).addTo(map)

Adding a custom marker should be as simple as shown here:

https://leafletjs.com/examples/custom-icons/

var greenIcon = L.icon({
    iconUrl: 'leaf-green.png',
    shadowUrl: 'leaf-shadow.png',

    iconSize:     [38, 95], // size of the icon
    shadowSize:   [50, 64], // size of the shadow
    iconAnchor:   [22, 94], // point of the icon which will correspond to marker's location
    shadowAnchor: [4, 62],  // the same for the shadow
    popupAnchor:  [-3, -76] // point from which the popup should open relative to the iconAnchor
});

L.marker([51.5, -0.09], {icon: greenIcon}).addTo(map);

I only have one problem: In my local development system the leaflet L object is available in the “onload_post_render” hook, where I would like to perform some map settings.

However, in the live system the object is not available in the hook. It is, however, available on the console after the page is fully loaded.

Any ideas how to access the L object in the hook?

Best regards,
Dom

Would this flow work in v14 as well? For some reason the view is not changing. i have changed the map_defaults.js to this:

// Make sure we have a dictionary to add our custom settings
const map_settings = frappe.provide(“frappe.utils.map_defaults”);

// Center and zoomlevel can be copied from the URL of
// the map view at openstreetmap.org.

// New default location (Perth City Centre).
map_settings.center = [-31.955435, 115.857642];
// new zoomlevel: see the whole country, not just a single city
map_settings.zoom = 6;

// Use a different map: satellite instead of streets
// Examples can be found at Leaflet Provider Demo
map_settings.tiles =
https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}”;
map_settings.attribution =
“Tiles © Esri — Source: Esri, i-cubed, USDA, USGS, AEX, GeoEye, Getmapping, Aerogrid, IGN, IGP, UPR-EGP, and the GIS User Community”;

did you manage to resolve the problem?

you can access the L object from anywhere by refernecing it with

window.L

@rmeyer really very helpfull and thank you so much for contributing…

Do you have any idea how can i limit no.of cordinate it loads…

i have like 3,00,000 records in a doctype and when i go to map view it just freezes the browser, i have changed server too but no luck, problem is actually on the client side, actually chrome is not able to handle so much data…

any idea buddy how to limit the loading of reacord in map view ?

This will definitely need software development, probably as a core contribution. No easy way to achieve this, I’m afraid…