widgets.py 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. from wtforms.widgets import TextArea
  2. def lat(pt):
  3. return getattr(pt, "lat", getattr(pt, "x", pt[0]))
  4. def lng(pt):
  5. return getattr(pt, "lng", getattr(pt, "y", pt[1]))
  6. class LeafletWidget(TextArea):
  7. data_role = 'leaflet'
  8. """
  9. `Leaflet <http://leafletjs.com/>`_ styled map widget. Inherits from
  10. `TextArea` so that geographic data can be stored via the <textarea>
  11. (and edited there if the user's browser does not have Javascript).
  12. You must include leaflet.js, form.js and leaflet stylesheet for it to
  13. work. You also need leaflet.draw.js (and its stylesheet) for it to be
  14. editable.
  15. """
  16. def __init__(
  17. self, width='auto', height=350, center=None,
  18. zoom=None, min_zoom=None, max_zoom=None, max_bounds=None):
  19. self.width = width
  20. self.height = height
  21. self.center = center
  22. self.zoom = zoom
  23. self.min_zoom = min_zoom
  24. self.max_zoom = max_zoom
  25. self.max_bounds = max_bounds
  26. def __call__(self, field, **kwargs):
  27. kwargs.setdefault('data-role', self.data_role)
  28. gtype = getattr(field, "geometry_type", "GEOMETRY")
  29. kwargs.setdefault('data-geometry-type', gtype)
  30. # set optional values from constructor
  31. if "data-width" not in kwargs:
  32. kwargs["data-width"] = self.width
  33. if "data-height" not in kwargs:
  34. kwargs["data-height"] = self.height
  35. if self.center:
  36. kwargs["data-lat"] = lat(self.center)
  37. kwargs["data-lng"] = lng(self.center)
  38. if self.zoom:
  39. kwargs["data-zoom"] = self.zoom
  40. if self.min_zoom:
  41. kwargs["data-min-zoom"] = self.min_zoom
  42. if self.max_zoom:
  43. kwargs["data-max-zoom"] = self.max_zoom
  44. if self.max_bounds:
  45. if getattr(self.max_bounds, "bounds"):
  46. # this is a Shapely geometric object
  47. minx, miny, maxx, maxy = self.max_bounds.bounds
  48. elif len(self.max_bounds) == 4:
  49. # this is a list of four values
  50. minx, miny, maxx, maxy = self.max_bounds
  51. else:
  52. # this is a list of two points
  53. minx = lat(self.max_bounds[0])
  54. miny = lng(self.max_bounds[0])
  55. maxx = lat(self.max_bounds[1])
  56. maxy = lng(self.max_bounds[1])
  57. kwargs["data-max-bounds-sw-lat"] = minx
  58. kwargs["data-max-bounds-sw-lng"] = miny
  59. kwargs["data-max-bounds-ne-lat"] = maxx
  60. kwargs["data-max-bounds-ne-lng"] = maxy
  61. return super(LeafletWidget, self).__call__(field, **kwargs)