A simple map & geolocation field, built on top of open-source services and Mapbox. Kirby 3 only.

Last update: Apr 24, 2022

Kirby Locator

A simple map & geolocation field, built on top of open-source services and Mapbox.

screenshot


Overview

This plugin is completely free and published under the MIT license. However, if you are using it in a commercial project and want to help me keep up with maintenance, please consider making a donation of your choice or purchasing your license(s) through my affiliate link.


1. Installation

Download and copy this repository to /site/plugins/locator

Alternatively, you can install it with composer: composer require sylvainjule/locator


2. Setup

Out of the box, the field is set to use open-source services both for geocoding (Nominatim) and tiles-rendering (Positron), without any API-key requirements.

Keep in mind that these services are bound by strict usage policies, always double-check if your usage is compatible. Otherwise, please set-up the field to use Mapbox, see details below.

mymap:
  label: Location
  type: locator

3. Tile-servers

3.1. Open-source / free tiles

tiles-opensource-2

You can pick one of the 4 free tile servers included:

  1. wikimedia (Terms of Use)
  2. openstreetmap (Terms of Use)
  3. positron (default, Terms of Use [Under Free Basemaps Terms of Service])
  4. voyager (Terms of Use [Under Free Basemaps Terms of Service])
mymap:
  type: locator
  tiles: positron

You can also set this globally in your installation's main config.php, then you won't have to configure it in every blueprint:

return array(
    'sylvainjule.locator.tiles' => 'positron',
);

3.2. Mapbox tiles

tiles-mapbox-2

  1. mapbox.outdoorsmapbox/outdoors-v11 (default mapbox theme)
  2. mapbox.streetsmapbox/streets-v11
  3. mapbox.lightmapbox/light-v10
  4. mapbox.darkmapbox/dark-v10

In case your usage doesn't fall into the above policies (or if you don't want to rely on those services), you can set-up the field to use Mapbox' tiles.

Leaflet doesn't render vector-maps, therefore you will not be able to use custom-styles edited with Mapbox Studio, only the public Mapbox tile-layers (listed above).

You will have to set both the id of the tiles you want to use and your mapbox public key in your installation's main config.php:

return array(
    'sylvainjule.locator.mapbox.id'    => 'mapbox/outdoors-v11',
    'sylvainjule.locator.mapbox.token' => 'pk.vdf561vf8...',
);

You can now explicitely state in your blueprint that you want to use Mapbox tiles:

mymap:
  type: locator
  tiles: mapbox

You can also set this globally in your installation's main config.php, then you won't have to configure it in every blueprint:

return array(
    'sylvainjule.locator.tiles' => 'mapbox',
);

4. Geocoding services

4.1. Open-source API (Nominatim)

This is the default geocoding service. It doesn't require any additional configuration, but please double-check if your needs fit the Nominatim Usage Policy.

mymap:
  type: locator
  geocoding: nominatim

4.2. Mapbox API

In case your usage doesn't fall into the above policy (or if you don't want to use Nominatim), you can set-up the field to use Mapbox API.

If you haven't already, you will have to set your mapbox public key in your installation's main config.php:

return array(
    'sylvainjule.locator.mapbox.token' => 'pk.vdf561vf8...',
);

You can now explicitely state in your blueprint that you want to use Mapbox as a geocoding service:

mymap:
  type: locator
  geocoding: mapbox

You can also set this globally in your installation's main config.php, then you won't have to configure it in every blueprint:

return array(
    'sylvainjule.locator.geocoding' => 'mapbox',
);

5. Per-field options

5.1. center

The coordinates of the center of the map, if the field has no stored value. Default is {lat: 48.864716, lon: 2.349014} (Paris, FR).

mymap:
  type: locator
  center:
    lat: 48.864716
    lon: 2.349014

5.2. zoom

The min, default and max zoom values, where default will be the one used on every first-load of the map. Default is: {min: 2, default: 12, max: 18}.

mymap:
  type: locator
  zoom:
    min: 2
    default: 12
    max: 18

5.3. saveZoom

Whether the field should store the zoom level of the map when the marker was added, and use it as default zoom value afterwards. Default is false.

mymap:
  type: locator
  saveZoom: false

5.4. autoSaveZoom

Whether the field should store the zoom level of the map when the user changes the zoom manually, and use it as default zoom value afterwards. Default is false.

mymap:
  type: locator
  autoSaveZoom: false

5.5. display

The informations to be displayed in the panel. Note that it will only hide them from the panel view, they will still be stored (if available) in the .txt file. To be picked from lat, lon, number, address, postcode, city and country. Default includes them all.

mymap:
  type: locator
  display:
    - lat
    - lon
    - number
    - address
    - postcode
    - city
    - country

5.6. draggable

If set to true, the marker will be repositionable in case search result isn't precise enough. After being moved, only the new lat and lng will be stored. Default is true.

5.7. autocomplete

If set to true, when Mapbox is used for geocoding, you will be presented up to 5 suggestions while typing your request. Default is true.

5.8. liststyle

liststyle

The style of the informations block, either columns or table. Default is table.

mymap:
  type: locator
  liststyle: table

5.9. marker

The color of the marker used, either dark or light (in case you are using mapbox.dark as your tile-layer). Default is dark.

mymap:
  type: locator
  marker: dark

5.10. language

If this options is set with an ISO 639-1 code (en, fr, de, etc.), the geocoding service will return results in the requested language if available. Default is false.

mymap:
  type: locator
  language: false # or 'de' | 'fr' | 'en' | …

6. Global options

The same options are available globally, which means you can set them all in your installation's config.php file and don't worry about setting it up individually afterwards:

return array(
    'sylvainjule.locator.center.lat'   => 48.864716,
    'sylvainjule.locator.center.lon'   => 2.349014,
    'sylvainjule.locator.zoom.min'     => 2,
    'sylvainjule.locator.zoom.default' => 12,
    'sylvainjule.locator.zoom.max'     => 18,
    'sylvainjule.locator.saveZoom'     => false,
    'sylvainjule.locator.autoSaveZoom' => false,
    'sylvainjule.locator.display'      => array('lat','lon','number','address','postcode','city','country'),
    'sylvainjule.locator.draggable'    => true,
    'sylvainjule.locator.autocomplete' => true,
    'sylvainjule.locator.liststyle'    => 'columns',
    'sylvainjule.locator.marker'       => 'dark',
    'sylvainjule.locator.language'     => false,
);

7. Front-end usage

The location data is stored as YAML and therefore needs to be decoded with the yaml method or using the toLocation method (see below):

$location = $page->mymap()->yaml();

Potential stored keys are:

  • lat (Latitude)
  • lon (Longitude)
  • number (Street number)
  • address (Street / road / place)
  • city (city / village)
  • country (country)

It is possible that the found location doesn't have one of those keys, which will therefore not be saved. It is important to always check if the key exists, and if it's not empty. Here's one way to do it:

$location = $page->mymap()->yaml();

if(!empty($location['postcode'])) {
    // there is a filled 'postcode' key
}
else {
    // there is no / an empty 'postcode' key
}

Alternatively, you can use the toLocation method to convert the value to a new collection, an use it kirby-style:

$location = $page->mymap()->toLocation();

// You now have access to
// $location->lat()
// $location->lon()
// ...

if($location->has('postcode')) {
    if($location->postcode()->isNotEmpty()) {
        // there is a filled 'postcode' key
    }
    else {
        // there is an empty 'postcode' key
    }
}
else {
  // there is no 'postcode' key
}

8. Credits

Services:

K2 fields:


9. License

MIT

GitHub

https://github.com/sylvainjule/kirby-locator
Comments
  • 1. [panel] mapbox doesn't load when using a token with url restrictions

    Hello Sylvain :)

    In the panel, Mapbox tiles can't be loaded when using a "non public" token. This is because the Kirby panel (since 3.4) blocks the referrer header (here).

    I don't know if this should be an issue with Locator, the Kirby panel or Leaflet.

    Locator could circumvent this issue by overriding the meta tag, with something like:

    document.querySelector("meta[name=referrer]").content = "origin";
    

    Kirby could solve this by using a less strict referrer policy. Something like "origin" or "no-referrer-when-downgrade"...

    Leaflet could solve this by adding a referrer policy to their tiles. Actually they did this a few days ago, but considering their last "release" was in september 2020, I don't know how long it will take to get this option in a stable version...

    I will crosspost an issue also on Kirby, and then link here.

    Reviewed by rasteiner at 2022-01-29 17:31
  • 2. The field type "location" does not exist

    While the plugin is correctly installed (and other plugins work fine) I somethow get the following error message with the latest nightly build:

    image

    "location" is the field name, not field type, in this case:

    fields:
      location:
        type: locator
    
    Reviewed by medienbaecker at 2018-11-15 14:07
  • 3. Store `osm_id`

    Hey there, this is somewhat related to #44, because saving a node's osm_id (which is already part of the response data) allows to retrieve the OSM link like that: https://www.openstreetmap.org/node/OSM_ID.

    Please consider storing this piece of information, otherwise I'll have to send a duplicate request to get the ID, which would be unnecessary. Please let me know what you think, or how to improve my PR so you might consider merging it.

    Cheers, and thank you for this plugin S1SYPHOS

    Reviewed by S1SYPHOS at 2021-10-06 16:31
  • 4. lon and lat output is with comma, instead of dot

    When I put marker on the map, I get lon and lat with dots, like: 58.529276, 1.449215, but when I search for location and save like it's found, output is with comma for one or both, like: 58,529276, 1.449215

    Reviewed by romanustin at 2021-01-13 14:42
  • 5. Follow the composer instructions

    Hi,

    please follow the kirby composer instructions

    Both the type field and the getkirby/composer-installer dependency are required for your plugin to work, otherwise it won't be loaded correctly by Kirby.

    The setup with a separate config.php file for Composer is no longer recommended as it can cause issues with the autoloading order. If you put your code directly into the index.php file and don't autoload it with Composer, Kirby will pick it up just fine.

    https://getkirby.com/docs/guide/plugins/plugin-setup-basic#the-composer-json


    Also what's the purpose of adding the vendor dir to git?

    Reviewed by chpio at 2019-03-13 12:20
  • 6. Doesn't work inside structures

    bildschirmfoto von 2018-12-05 17-12-19

    The red bar should be the locator field. When I decrease the indentation of the exact same field (to lift it out of the structure field) it displays and works as expected.

    Reviewed by REHvision at 2018-12-05 16:19
  • 7. composer installation fails

    Hi! I tried to install it with composer require sylvainjule/locator on dev-master 3.0.0-beta-6.17. But I get this error:

    [InvalidArgumentException]
      Could not find a matching version of package sylvainjule/locator. Check the package spelling, your version constrai
      nt and that the package is available in a stability which matches your minimum-stability (beta).
    
    Reviewed by MathiasGmeiner at 2018-11-14 19:41
  • 8. The field type "" does not exist

    I'm using Kirby 3.2.2 and getting this error when using the locator field. This is what my blueprint looks like:

    title: Location
    
    tabs:
      content:
        label: Content
        icon: document
        columns:
          - width: 2/3
            fields:
              page_content:
                label: Text
                type: textarea
                size: small
              mymap:
                label: Map
                type: locator
    

    image

    Reviewed by iv-agatha at 2019-07-18 22:14
  • 9. Unexpected values with "geocoding: mapbox"

    First of all thank you for this wonderful plugin.

    I'm not sure this is really an issue, but by setting geocoding: mapbox the latitude and longitude values are returned by the toLocation method with a comma and not with a dot.

    Nominatim: <?= $location->lat() ?> // 41.894802

    Mapbox: <?= $location->lat() ?> // 41,894802

    This difference can cause some problems in the frontend implementation of the map.

    In the content folder the values lat and lon are stored differently between mapbox and nominatim.

    Nominatim geocoding:

    Map: 
    
    lat: "41.894802"
    lon: "12.4853384"
    city: Roma
    country: Italia
    

    Mapbox geocoding:

    Map: 
    
    lat: 41.894802
    lon: 12.4853384
    city: Roma
    country: Italia
    
    Reviewed by marcomezzavilla at 2019-04-12 14:31
  • 10. The field type "wathever" does not exist

    Hello, I installed the last version of locator and an error message keeps popping in kirby's panel: "The field type "wathever" does not exist" I tried to change the field name and the massage still is the same, with the new name between the quotation marks. Here is a screenshot of the setup: Screenshot_2022-03-03-09-40-25_1920x1080 Normally everything should be fine but as I am learning coding, it could be my mistake... Thank you for your work, it would be great if locator was integrated in kirby, it seems an essential function to me.

    Reviewed by machineafumee at 2022-03-03 21:13
  • 11. Override panel referrerpolicy for Mapbox API calls

    This is what I believe to fix #46 – I ran some tests with the default positron maps in my setup and this appears to reliably change the panel's referrerpolicy meta setting to strict-origin-when-cross-origin before tile loading starts (Leaflet tileLayer event loading) and restore the original same-origin policy after loading tiles (tileLayer event load).

    The solution is heavily inspired by @rasteiner's workaround and intended as a temporary fix until Leaflet provides proper means to set a referrer policy for fetch. If it proves to work reliably, this is in my opinion the least invasive workaround, as it should not compromise privacy and security for any other fields in the panel (as the policy remains very strict as long as no tile interactions take place).

    It would be interesting to hear how this works with the Mapbox API setup and in other environments. The effect can be observed by checking the referrer policy for the tile files in the Devtools Network tab and/or by looking at the meta tag in Inspector view while refreshing/zooming/panning etc.

    Feedback and suggestions for improvements most welcome!

    Reviewed by sebastiangreger at 2022-02-02 22:38
  • 12. Save country code along other data

    In case this is possible from the data we can gather from the geolocation apis, it would be cool to include the country code in the data. This would allow showing a translated country name in the frontend by passing the country code to PHP internals, e.g. Locale::getDisplayRegion.

    Reviewed by renestalder at 2022-05-23 13:09
  • 13. Feature suggestion: Panel view to display a collection of locator-pages on a map

    I've been using this plugin for a handful of sites that include, in some way or another, a collection of multiple pages with locator fields. In the frontend, all pages are output as a set of markers on a full-screen map, each having a popup or linking to a page etc.

    I'd like to suggest building an "all locations"-view as an optional panel section. This could display multiple markers on a large map, each marker linking to the respective page in the panel. I know it will come in handy at least for my current/upcoming projects.

    Is this something you would consider building/reviewing a pull request for? I'll be working on at least one or two map sites this year, so these projects could justify helping out with such an addition to this plugin.

    Reviewed by moevbiz at 2022-02-04 13:18
🗺 Vue Mapbox GL - A small components library to use Mapbox GL in Vue

?? Vue Mapbox GL A small components library to use Mapbox GL in Vue. Installation & usage Have a look at the small guide for information on how to set

Mar 21, 2022
Annotate maps and generate GeoJSON in Kirby by drawing markers, paths and shapes
Annotate maps and generate GeoJSON in Kirby by drawing markers, paths and shapes

Kirby Mapnotator Annotate maps and generate GeoJSON in Kirby by drawing markers, paths and shapes. Overview This plugin is completely free and publish

Apr 27, 2022
A Vue.js component for Mapbox GL JS

Mapbox GL JS Vue.js A simple lightweight (9kb/3kb gzipped) Mapbox GL JS Vue component. Demo Installation Setup Props Events Plugins Popups Development

Mar 21, 2022
Vuejs 2 components for interacting with mapbox-gl-js

VueMapbox Combine powers of Vue.js and Mapbox Gl JS Vue-mapbox is wrapper around Mapbox GL JS library that provides vueish-way to interact with the ma

May 16, 2022
A cloned & maintained version of vue-mapbox

V-Mapbox ?? Combine powers of Vue.js and Mapbox GL JS NOTE: This is a maintained version of vue-mapbox V-Mapbox is wrapper around Mapbox GL JS library

May 15, 2022
Wrapper for vue-mapbox-geocoder

v-mapbox-geocoder ?? v-mapbox plugin for mapbox-gl-geocoder support. Setup First of all you need to install mapbox-gl-geocoder and v-mapbox. See v-map

Sep 18, 2021
A wrapper component for consuming Google Maps API built on top of VueJs v2.

A wrapper component for consuming Google Maps API built on top of VueJs v2. Fork of the popular vue-google-maps plugin.

May 14, 2022
Directus-extension-svgmap-picker-interface - Select a value from a SVG Map box, built using vue.js
Directus-extension-svgmap-picker-interface - Select a value from a SVG Map box, built using vue.js

This extension is under development, it may take breaking changes. SVG Map Picke

Apr 8, 2022
a simple component to generate an static google map
a simple component to generate an static google map

vue-static-map a simple component to generate an static google map Google Documentation Demo SandBox JSBin example Requirements Vue 2.X.X Usage Instal

May 17, 2022
Baidu Map components for Vue 2.x
Baidu Map components for Vue 2.x

VUE BAIDU MAP Baidu Map components for Vue 2.x Languages 中文 English Documentation https://dafrok.github.io/vue-baidu-map Get Start Installation npm i

May 24, 2022
Choropleth Map component for Vue.js

vue-choropleth Vue components to display a choropleth map given a certain GeoJSON and another datasource to show information from. Using Vue2Leaflet H

Feb 12, 2022
Web map Vue components with the power of OpenLayers

VueLayers Web map Vue components with the power of OpenLayers Overview VueLayers is components library that brings the powerful OpenLayers API to the

May 19, 2022
vue google map custom marker component
vue google map custom marker component

vue2-gmap-custom-marker This component allows you to display custom HTML content on the map using Overlay. This component is an adaptation of the Goog

May 17, 2022
New Sayobot Map Downloader Written by [email protected], [email protected], [email protected]
New Sayobot Map Downloader Written by Electron@12, Vite@2, Vue@3

SayoDownloader This software only provide in Chinese! 一个全新设计的小夜地图下载器

Feb 20, 2022
Web map Vue 3.x components with the power of OpenLayers
Web map Vue 3.x components with the power of OpenLayers

vue3-openlayers Web map Vue components with the power of OpenLayers Overview vue3-openlayers is components library that brings the powerful OpenLayers

May 26, 2022
A Vue JS component for displaying dynamic data on a world map.

This is no longer being maintained, please do not open issues or PRs. Vue World Map A Vue JS Component for displaying dynamic data on a world map. Map

May 10, 2022
A set of Vue.js components to display an interactive SVG map

vue-svg-map A set of Vue.js components to display an interactive SVG map. Demo Take a look at the live demo! Installation npm npm install --save vue-s

May 26, 2022
A quick way to start a web map application with Vue.js using MapLibre GL JS.
A quick way to start a web map application with Vue.js using MapLibre GL JS.

Vue.js map using MapLibre GL JS A quick way to start a web map application with Vue.js using MapLibre GL JS. A simple fullscreen map application is us

May 19, 2022
This component allows you to display custom HTML content on the map using Overlay
This component allows you to display custom HTML content on the map using Overlay

vue3-gmap-custom-marker This component allows you to display custom HTML content on the map using Overlay. This component is an update (a fork) from e

Apr 1, 2022