A Google Maps widget for Wagtail that supports both GeoDjango PointField, StreamField and CharField.
Project description
|Build Status| |PyPI version|
Wagtail-Geo-Widget
==================
A Google Maps widget for Wagtail that supports both GeoDjango
PointField, StreamField and the standard CharField.
.. figure:: https://raw.githubusercontent.com/frojd/wagtail-geo-widget/develop/img/screen1.png
:alt: Screen1
Screen1
Requirements
------------
- Python 2.7 / Python 3.5+
- Wagtail 1.13+ and Django
- A API key for Google Maps
Installation
------------
Install the library with pip:
::
$ pip install wagtailgeowidget
Quick Setup
-----------
Make sure ``wagtailgeowidget`` is added to your ``INSTALLED_APPS``.
.. code:: python
INSTALLED_APPS = (
# ...
'wagtailgeowidget',
)
Obtain a Google Maps API key and add it to your Django settings
``GOOGLE_MAPS_V3_APIKEY``
This should be enough to get started.
Usage
-----
- `Standard
CharField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#standard-charfield>`__
- `StreamField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#streamfield>`__
- `GeoDjango/PointField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#geodjango-pointfield>`__
Standard CharField
------------------
Define a CharField representing your location, then add a GeoPanel.
.. code:: python
from django.db import models
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPage(Page):
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
GeoPanel('location'),
]
The data is stored as a ``GEOSGeometry`` string (Example:
``SRID=4326;POINT(17.35448867187506 59.929179873751934)``. To use the
data, we recommend that you add helper methods to your model.
.. code:: python
from django.utils.functional import cached_property
from wagtailgeowidget.helpers import geosgeometry_str_to_struct
class MyPage(Page):
# ...
@cached_property
def point(self):
return geosgeometry_str_to_struct(self.location)
@property
def lat(self):
return self.point['y']
@property
def lng(self):
return self.point['x']
NOTE: While this implementation is quick and easy to setup, the drawback
is that it will prevent you from making spatial queries, if that is what
you need, use the `GeoDjango/Pointer field <#geodjango-pointfield>`__
implementation instead.
With an address field
~~~~~~~~~~~~~~~~~~~~~
The panel accepts an ``address_field`` if you want to use the map in
coordination with a geo-lookup (like the screenshot on top).
.. code:: python
from django.db import models
from django.utils.translation import ugettext as _
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPageWithAddressField(Page):
address = models.CharField(max_length=250, blank=True, null=True)
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('address'),
GeoPanel('location', address_field='address'),
], _('Geo details')),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L82>`__.
StreamField
-----------
To add a map in a StreamField, import and use the GeoBlock.
.. code:: python
from wagtail.core.models import Page
from wagtail.core.fields import StreamField
from wagtailgeowidget.blocks import GeoBlock
class GeoStreamPage(Page):
body = StreamField([
('map', GeoBlock()),
])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
The data is stored as a json struct and you can access it by using
value.lat / value.lng
.. code:: html
<article>
{% for map_block in page.stream_field %}
<hr />
{{ map_block.value }}
<p>Latitude: {{ map_block.value.lat}}</p>
<p>Longitude: {{ map_block.value.lng }}</p>
{% endfor %}
</article>
.. _with-an-address-field-1:
With an address field
~~~~~~~~~~~~~~~~~~~~~
Make sure you define a field representing the address at the same level
as your GeoBlock, either in the StreamField or in a StructBlock.
.. code:: python
from wagtail.admin.edit_handlers import StreamFieldPanel
from wagtailgeowidget.blocks import GeoBlock
class GeoStreamPage(Page):
body = StreamField([
('map_struct', blocks.StructBlock([
('address', blocks.CharBlock(required=True)),
('map', GeoBlock(address_field='address')),
]))
])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L64>`__.
GeoDjango (PointField)
----------------------
First make sure you have
`GeoDjango <https://docs.djangoproject.com/en/1.10/ref/contrib/gis/>`__
correctly setup and a PointField field defined in your model, then add a
GeoPanel among your content_panels.
.. code:: python
from django.contrib.gis.db import models
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPage(Page):
location = models.PointField(srid=4326, null=True, blank=True)
content_panels = Page.content_panels + [
GeoPanel('location'),
]
.. _with-an-address-field-2:
With an address field
~~~~~~~~~~~~~~~~~~~~~
The panel accepts an ``address_field`` if you want to use the map in
coordination with a geo-lookup (like the screenshot on top).
.. code:: python
from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPageWithAddressField(Page):
address = models.CharField(max_length=250, blank=True, null=True)
location = models.PointField(srid=4326, null=True, blank=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('address'),
GeoPanel('location', address_field='address'),
], _('Geo details')),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L35>`__.
Settings
--------
- ``GOOGLE_MAPS_V3_APIKEY``: API key for Google Maps (required).
- ``GOOGLE_MAPS_V3_LANGUAGE``: The language you want to set for the map
interface (default is ``en``)
- ``GEO_WIDGET_DEFAULT_LOCATION``: Default map location when no
coordinates are set, accepts a dict with lat and lng keys (default is
``{'lat': 59.3293, 'lng': 18.0686}`` that is Stockholm/Sweden).
- ``GEO_WIDGET_ZOOM``: Default zoom level for map (7 is default).
FAQ
---
.. raw:: html
<details>
This library no longer works on Wagtail 1.13 LTS!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wagtail 2.0 introduced a couple of breaking changes regarding the field
api that required us to rewrite the ``GeoPanel`` component. To keep
compability with Wagtail 1.13 we have moved the original ``GeoPanel`` to
the package ``wagtailgeowidget.legacy_edit_handlers``.
.. code:: python
from wagtail.wagtailcore.models import Page
from wagtailgeowidget.legacy_edit_handlers import GeoPanel
class StandardPage(Page):
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
GeoPanel('location')
]
Please note that this edit handler will be removed as soon as the
Wagtail 1.13 expires (which is April 2018).
Is it possible to hide the lat/lng field?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, by passing ``hide_latlng=True`` to the GeoPanel.
.. code:: python
GeoPanel('location', address_field='address', hide_latlng=True)
It is currently not supported in streamfields.
.. raw:: html
</details>
Roadmap
-------
- [x] Editable map widget for GeoDjango PointerField
- [x] Global default map location
- [x] Streamfield map widget
- [ ] Templatetag for rendering basic maps
Contributing
------------
Want to contribute? Awesome. Just send a pull request.
License
-------
Wagtail-Geo-Widget is released under the `MIT
License <http://www.opensource.org/licenses/MIT>`__.
.. |Build Status| image:: https://travis-ci.org/Frojd/wagtail-geo-widget.svg?branch=master
:target: https://travis-ci.org/Frojd/wagtail-geo-widget
.. |PyPI version| image:: https://badge.fury.io/py/wagtailgeowidget.svg
:target: https://badge.fury.io/py/wagtailgeowidget
Wagtail-Geo-Widget
==================
A Google Maps widget for Wagtail that supports both GeoDjango
PointField, StreamField and the standard CharField.
.. figure:: https://raw.githubusercontent.com/frojd/wagtail-geo-widget/develop/img/screen1.png
:alt: Screen1
Screen1
Requirements
------------
- Python 2.7 / Python 3.5+
- Wagtail 1.13+ and Django
- A API key for Google Maps
Installation
------------
Install the library with pip:
::
$ pip install wagtailgeowidget
Quick Setup
-----------
Make sure ``wagtailgeowidget`` is added to your ``INSTALLED_APPS``.
.. code:: python
INSTALLED_APPS = (
# ...
'wagtailgeowidget',
)
Obtain a Google Maps API key and add it to your Django settings
``GOOGLE_MAPS_V3_APIKEY``
This should be enough to get started.
Usage
-----
- `Standard
CharField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#standard-charfield>`__
- `StreamField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#streamfield>`__
- `GeoDjango/PointField <https://github.com/Frojd/wagtail-geo-widget/blob/develop/README.md#geodjango-pointfield>`__
Standard CharField
------------------
Define a CharField representing your location, then add a GeoPanel.
.. code:: python
from django.db import models
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPage(Page):
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
GeoPanel('location'),
]
The data is stored as a ``GEOSGeometry`` string (Example:
``SRID=4326;POINT(17.35448867187506 59.929179873751934)``. To use the
data, we recommend that you add helper methods to your model.
.. code:: python
from django.utils.functional import cached_property
from wagtailgeowidget.helpers import geosgeometry_str_to_struct
class MyPage(Page):
# ...
@cached_property
def point(self):
return geosgeometry_str_to_struct(self.location)
@property
def lat(self):
return self.point['y']
@property
def lng(self):
return self.point['x']
NOTE: While this implementation is quick and easy to setup, the drawback
is that it will prevent you from making spatial queries, if that is what
you need, use the `GeoDjango/Pointer field <#geodjango-pointfield>`__
implementation instead.
With an address field
~~~~~~~~~~~~~~~~~~~~~
The panel accepts an ``address_field`` if you want to use the map in
coordination with a geo-lookup (like the screenshot on top).
.. code:: python
from django.db import models
from django.utils.translation import ugettext as _
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPageWithAddressField(Page):
address = models.CharField(max_length=250, blank=True, null=True)
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('address'),
GeoPanel('location', address_field='address'),
], _('Geo details')),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L82>`__.
StreamField
-----------
To add a map in a StreamField, import and use the GeoBlock.
.. code:: python
from wagtail.core.models import Page
from wagtail.core.fields import StreamField
from wagtailgeowidget.blocks import GeoBlock
class GeoStreamPage(Page):
body = StreamField([
('map', GeoBlock()),
])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
The data is stored as a json struct and you can access it by using
value.lat / value.lng
.. code:: html
<article>
{% for map_block in page.stream_field %}
<hr />
{{ map_block.value }}
<p>Latitude: {{ map_block.value.lat}}</p>
<p>Longitude: {{ map_block.value.lng }}</p>
{% endfor %}
</article>
.. _with-an-address-field-1:
With an address field
~~~~~~~~~~~~~~~~~~~~~
Make sure you define a field representing the address at the same level
as your GeoBlock, either in the StreamField or in a StructBlock.
.. code:: python
from wagtail.admin.edit_handlers import StreamFieldPanel
from wagtailgeowidget.blocks import GeoBlock
class GeoStreamPage(Page):
body = StreamField([
('map_struct', blocks.StructBlock([
('address', blocks.CharBlock(required=True)),
('map', GeoBlock(address_field='address')),
]))
])
content_panels = Page.content_panels + [
StreamFieldPanel('body'),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L64>`__.
GeoDjango (PointField)
----------------------
First make sure you have
`GeoDjango <https://docs.djangoproject.com/en/1.10/ref/contrib/gis/>`__
correctly setup and a PointField field defined in your model, then add a
GeoPanel among your content_panels.
.. code:: python
from django.contrib.gis.db import models
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPage(Page):
location = models.PointField(srid=4326, null=True, blank=True)
content_panels = Page.content_panels + [
GeoPanel('location'),
]
.. _with-an-address-field-2:
With an address field
~~~~~~~~~~~~~~~~~~~~~
The panel accepts an ``address_field`` if you want to use the map in
coordination with a geo-lookup (like the screenshot on top).
.. code:: python
from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
from wagtail.admin.edit_handlers import FieldPanel, MultiFieldPanel
from wagtailgeowidget.edit_handlers import GeoPanel
class MyPageWithAddressField(Page):
address = models.CharField(max_length=250, blank=True, null=True)
location = models.PointField(srid=4326, null=True, blank=True)
content_panels = Page.content_panels + [
MultiFieldPanel([
FieldPanel('address'),
GeoPanel('location', address_field='address'),
], _('Geo details')),
]
For more examples, look at the
`example <https://github.com/Frojd/wagtail-geo-widget/blob/develop/example/geopage/models.py#L35>`__.
Settings
--------
- ``GOOGLE_MAPS_V3_APIKEY``: API key for Google Maps (required).
- ``GOOGLE_MAPS_V3_LANGUAGE``: The language you want to set for the map
interface (default is ``en``)
- ``GEO_WIDGET_DEFAULT_LOCATION``: Default map location when no
coordinates are set, accepts a dict with lat and lng keys (default is
``{'lat': 59.3293, 'lng': 18.0686}`` that is Stockholm/Sweden).
- ``GEO_WIDGET_ZOOM``: Default zoom level for map (7 is default).
FAQ
---
.. raw:: html
<details>
This library no longer works on Wagtail 1.13 LTS!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Wagtail 2.0 introduced a couple of breaking changes regarding the field
api that required us to rewrite the ``GeoPanel`` component. To keep
compability with Wagtail 1.13 we have moved the original ``GeoPanel`` to
the package ``wagtailgeowidget.legacy_edit_handlers``.
.. code:: python
from wagtail.wagtailcore.models import Page
from wagtailgeowidget.legacy_edit_handlers import GeoPanel
class StandardPage(Page):
location = models.CharField(max_length=250, blank=True, null=True)
content_panels = Page.content_panels + [
GeoPanel('location')
]
Please note that this edit handler will be removed as soon as the
Wagtail 1.13 expires (which is April 2018).
Is it possible to hide the lat/lng field?
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Yes, by passing ``hide_latlng=True`` to the GeoPanel.
.. code:: python
GeoPanel('location', address_field='address', hide_latlng=True)
It is currently not supported in streamfields.
.. raw:: html
</details>
Roadmap
-------
- [x] Editable map widget for GeoDjango PointerField
- [x] Global default map location
- [x] Streamfield map widget
- [ ] Templatetag for rendering basic maps
Contributing
------------
Want to contribute? Awesome. Just send a pull request.
License
-------
Wagtail-Geo-Widget is released under the `MIT
License <http://www.opensource.org/licenses/MIT>`__.
.. |Build Status| image:: https://travis-ci.org/Frojd/wagtail-geo-widget.svg?branch=master
:target: https://travis-ci.org/Frojd/wagtail-geo-widget
.. |PyPI version| image:: https://badge.fury.io/py/wagtailgeowidget.svg
:target: https://badge.fury.io/py/wagtailgeowidget
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
wagtailgeowidget-4.0.5.tar.gz
(13.4 kB
view hashes)