Skip to content

A Google Maps widget for Wagtail that supports both GeoDjango PointField, StreamField and the standard CharField.

License

Notifications You must be signed in to change notification settings

infoportugal/wagtail-geo-widget

 
 

Repository files navigation

Build Status PyPI version

Wagtail-Geo-Widget

A Google Maps widget for Wagtail that supports both GeoDjango PointField, StreamField and the standard CharField.

Screen1

Requirements

  • Python 2.7 / Python 3.5+
  • Wagtail 1.8+ 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.

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

Define a CharField representing your location, then add a GeoPanel.

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.

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 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).

from django.db import models
from django.utils.translation import ugettext as _
from wagtail.wagtailadmin.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.

StreamField

To add a map in a StreamField, import and use the GeoBlock.

from wagtail.wagtailcore.models import Page
from wagtail.wagtailcore.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

<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

Make sure you define a field representing the address at the same level as your GeoBlock, either in the StreamField or in a StructBlock.

from wagtail.wagtailadmin.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.

GeoDjango (PointField)

First make sure you have GeoDjango correctly setup and a PointField field defined in your model, then add a GeoPanel among your content_panels.

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

The panel accepts an address_field if you want to use the map in coordination with a geo-lookup (like the screenshot on top).

from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
from wagtail.wagtailadmin.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.

Settings

  • GOOGLE_MAPS_V3_APIKEY: API key for Google Maps (required).
  • GEO_WIDGET_DEFAULT_LOCATION: Default map location when no coordinates are set, accepts a dict with lat and lng keys (required, default is {'lat': 59.3293, 'lng': 18.0686} that is Stockholm/Sweden).
  • GEO_WIDGET_ZOOM: Default zoom level for map (required, 7 is default).

Roadmap

  • Editable map widget for GeoDjango PointerField
  • Global default map location
  • 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.

About

A Google Maps widget for Wagtail that supports both GeoDjango PointField, StreamField and the standard CharField.

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages

  • Python 73.6%
  • JavaScript 15.7%
  • HTML 9.8%
  • Other 0.9%