Refs #27656 -- Updated django.contrib docstring verb style according to PEP 257.
This commit is contained in:
parent
3f62d20a9b
commit
5411821e3b
|
@ -1,6 +1,6 @@
|
||||||
def register(*models, site=None):
|
def register(*models, site=None):
|
||||||
"""
|
"""
|
||||||
Registers the given model(s) classes and wrapped ModelAdmin class with
|
Register the given model(s) classes and wrapped ModelAdmin class with
|
||||||
admin site:
|
admin site:
|
||||||
|
|
||||||
@register(Author)
|
@register(Author)
|
||||||
|
|
|
@ -33,13 +33,13 @@ class ListFilter:
|
||||||
|
|
||||||
def has_output(self):
|
def has_output(self):
|
||||||
"""
|
"""
|
||||||
Returns True if some choices would be output for this filter.
|
Return True if some choices would be output for this filter.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('subclasses of ListFilter must provide a has_output() method')
|
raise NotImplementedError('subclasses of ListFilter must provide a has_output() method')
|
||||||
|
|
||||||
def choices(self, changelist):
|
def choices(self, changelist):
|
||||||
"""
|
"""
|
||||||
Returns choices ready to be output in the template.
|
Return choices ready to be output in the template.
|
||||||
|
|
||||||
`changelist` is the ChangeList to be displayed.
|
`changelist` is the ChangeList to be displayed.
|
||||||
"""
|
"""
|
||||||
|
@ -47,13 +47,13 @@ class ListFilter:
|
||||||
|
|
||||||
def queryset(self, request, queryset):
|
def queryset(self, request, queryset):
|
||||||
"""
|
"""
|
||||||
Returns the filtered queryset.
|
Return the filtered queryset.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('subclasses of ListFilter must provide a queryset() method')
|
raise NotImplementedError('subclasses of ListFilter must provide a queryset() method')
|
||||||
|
|
||||||
def expected_parameters(self):
|
def expected_parameters(self):
|
||||||
"""
|
"""
|
||||||
Returns the list of parameter names that are expected from the
|
Return the list of parameter names that are expected from the
|
||||||
request's query string and that will be used by this filter.
|
request's query string and that will be used by this filter.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('subclasses of ListFilter must provide an expected_parameters() method')
|
raise NotImplementedError('subclasses of ListFilter must provide an expected_parameters() method')
|
||||||
|
@ -82,9 +82,9 @@ class SimpleListFilter(ListFilter):
|
||||||
|
|
||||||
def value(self):
|
def value(self):
|
||||||
"""
|
"""
|
||||||
Returns the value (in string format) provided in the request's
|
Return the value (in string format) provided in the request's
|
||||||
query string for this filter, if any. If the value wasn't provided then
|
query string for this filter, if any, or None if the value wasn't
|
||||||
returns None.
|
provided.
|
||||||
"""
|
"""
|
||||||
return self.used_parameters.get(self.parameter_name)
|
return self.used_parameters.get(self.parameter_name)
|
||||||
|
|
||||||
|
|
|
@ -377,9 +377,7 @@ class InlineFieldset(Fieldset):
|
||||||
|
|
||||||
|
|
||||||
class AdminErrorList(forms.utils.ErrorList):
|
class AdminErrorList(forms.utils.ErrorList):
|
||||||
"""
|
"""Store errors for the form/formsets in an add/change view."""
|
||||||
Stores all errors for the form/formsets in an add/change stage view.
|
|
||||||
"""
|
|
||||||
def __init__(self, form, inline_formsets):
|
def __init__(self, form, inline_formsets):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
|
|
||||||
|
|
|
@ -129,12 +129,12 @@ class LogEntry(models.Model):
|
||||||
return self.change_message
|
return self.change_message
|
||||||
|
|
||||||
def get_edited_object(self):
|
def get_edited_object(self):
|
||||||
"Returns the edited object represented by this log entry"
|
"""Return the edited object represented by this log entry."""
|
||||||
return self.content_type.get_object_for_this_type(pk=self.object_id)
|
return self.content_type.get_object_for_this_type(pk=self.object_id)
|
||||||
|
|
||||||
def get_admin_url(self):
|
def get_admin_url(self):
|
||||||
"""
|
"""
|
||||||
Returns the admin URL to edit the object represented by this log entry.
|
Return the admin URL to edit the object represented by this log entry.
|
||||||
"""
|
"""
|
||||||
if self.content_type and self.object_id:
|
if self.content_type and self.object_id:
|
||||||
url_name = 'admin:%s_%s_change' % (self.content_type.app_label, self.content_type.model)
|
url_name = 'admin:%s_%s_change' % (self.content_type.app_label, self.content_type.model)
|
||||||
|
|
|
@ -200,7 +200,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
"""
|
"""
|
||||||
If the ModelAdmin specifies ordering, the queryset should respect that
|
If the ModelAdmin specifies ordering, the queryset should respect that
|
||||||
ordering. Otherwise don't specify the queryset, let the field decide
|
ordering. Otherwise don't specify the queryset, let the field decide
|
||||||
(returns None in that case).
|
(return None in that case).
|
||||||
"""
|
"""
|
||||||
related_admin = self.admin_site._registry.get(db_field.remote_field.model)
|
related_admin = self.admin_site._registry.get(db_field.remote_field.model)
|
||||||
if related_admin is not None:
|
if related_admin is not None:
|
||||||
|
@ -321,7 +321,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def get_queryset(self, request):
|
def get_queryset(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a QuerySet of all model instances that can be edited by the
|
Return a QuerySet of all model instances that can be edited by the
|
||||||
admin site. This is used by changelist_view.
|
admin site. This is used by changelist_view.
|
||||||
"""
|
"""
|
||||||
qs = self.model._default_manager.get_queryset()
|
qs = self.model._default_manager.get_queryset()
|
||||||
|
@ -384,7 +384,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def to_field_allowed(self, request, to_field):
|
def to_field_allowed(self, request, to_field):
|
||||||
"""
|
"""
|
||||||
Returns True if the model associated with this admin should be
|
Return True if the model associated with this admin should be
|
||||||
allowed to be referenced by the specified field.
|
allowed to be referenced by the specified field.
|
||||||
"""
|
"""
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
|
@ -429,7 +429,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def has_add_permission(self, request):
|
def has_add_permission(self, request):
|
||||||
"""
|
"""
|
||||||
Returns True if the given request has permission to add an object.
|
Return True if the given request has permission to add an object.
|
||||||
Can be overridden by the user in subclasses.
|
Can be overridden by the user in subclasses.
|
||||||
"""
|
"""
|
||||||
opts = self.opts
|
opts = self.opts
|
||||||
|
@ -438,7 +438,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def has_change_permission(self, request, obj=None):
|
def has_change_permission(self, request, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns True if the given request has permission to change the given
|
Return True if the given request has permission to change the given
|
||||||
Django model instance, the default implementation doesn't examine the
|
Django model instance, the default implementation doesn't examine the
|
||||||
`obj` parameter.
|
`obj` parameter.
|
||||||
|
|
||||||
|
@ -453,7 +453,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def has_delete_permission(self, request, obj=None):
|
def has_delete_permission(self, request, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns True if the given request has permission to change the given
|
Return True if the given request has permission to change the given
|
||||||
Django model instance, the default implementation doesn't examine the
|
Django model instance, the default implementation doesn't examine the
|
||||||
`obj` parameter.
|
`obj` parameter.
|
||||||
|
|
||||||
|
@ -468,7 +468,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
def has_module_permission(self, request):
|
def has_module_permission(self, request):
|
||||||
"""
|
"""
|
||||||
Returns True if the given request has any permission in the given
|
Return True if the given request has any permission in the given
|
||||||
app label.
|
app label.
|
||||||
|
|
||||||
Can be overridden by the user in subclasses. In such case it should
|
Can be overridden by the user in subclasses. In such case it should
|
||||||
|
@ -481,7 +481,7 @@ class BaseModelAdmin(metaclass=forms.MediaDefiningClass):
|
||||||
|
|
||||||
|
|
||||||
class ModelAdmin(BaseModelAdmin):
|
class ModelAdmin(BaseModelAdmin):
|
||||||
"Encapsulates all admin options and functionality for a given model."
|
"""Encapsulate all admin options and functionality for a given model."""
|
||||||
|
|
||||||
list_display = ('__str__',)
|
list_display = ('__str__',)
|
||||||
list_display_links = ()
|
list_display_links = ()
|
||||||
|
@ -585,7 +585,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_model_perms(self, request):
|
def get_model_perms(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a dict of all perms for this model. This dict has the keys
|
Return a dict of all perms for this model. This dict has the keys
|
||||||
``add``, ``change``, and ``delete`` mapping to the True/False for each
|
``add``, ``change``, and ``delete`` mapping to the True/False for each
|
||||||
of those actions.
|
of those actions.
|
||||||
"""
|
"""
|
||||||
|
@ -603,7 +603,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_form(self, request, obj=None, **kwargs):
|
def get_form(self, request, obj=None, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a Form class for use in the admin add view. This is used by
|
Return a Form class for use in the admin add view. This is used by
|
||||||
add_view and change_view.
|
add_view and change_view.
|
||||||
"""
|
"""
|
||||||
if 'fields' in kwargs:
|
if 'fields' in kwargs:
|
||||||
|
@ -650,15 +650,15 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_changelist(self, request, **kwargs):
|
def get_changelist(self, request, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns the ChangeList class for use on the changelist page.
|
Return the ChangeList class for use on the changelist page.
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin.views.main import ChangeList
|
from django.contrib.admin.views.main import ChangeList
|
||||||
return ChangeList
|
return ChangeList
|
||||||
|
|
||||||
def get_object(self, request, object_id, from_field=None):
|
def get_object(self, request, object_id, from_field=None):
|
||||||
"""
|
"""
|
||||||
Returns an instance matching the field and value provided, the primary
|
Return an instance matching the field and value provided, the primary
|
||||||
key is used if no field is provided. Returns ``None`` if no match is
|
key is used if no field is provided. Return ``None`` if no match is
|
||||||
found or the object_id fails validation.
|
found or the object_id fails validation.
|
||||||
"""
|
"""
|
||||||
queryset = self.get_queryset(request)
|
queryset = self.get_queryset(request)
|
||||||
|
@ -672,7 +672,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_changelist_form(self, request, **kwargs):
|
def get_changelist_form(self, request, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a Form class for use in the Formset on the changelist page.
|
Return a Form class for use in the Formset on the changelist page.
|
||||||
"""
|
"""
|
||||||
defaults = {
|
defaults = {
|
||||||
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
"formfield_callback": partial(self.formfield_for_dbfield, request=request),
|
||||||
|
@ -685,7 +685,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_changelist_formset(self, request, **kwargs):
|
def get_changelist_formset(self, request, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns a FormSet class for use on the changelist page if list_editable
|
Return a FormSet class for use on the changelist page if list_editable
|
||||||
is used.
|
is used.
|
||||||
"""
|
"""
|
||||||
defaults = {
|
defaults = {
|
||||||
|
@ -699,7 +699,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_formsets_with_inlines(self, request, obj=None):
|
def get_formsets_with_inlines(self, request, obj=None):
|
||||||
"""
|
"""
|
||||||
Yields formsets and the corresponding inlines.
|
Yield formsets and the corresponding inlines.
|
||||||
"""
|
"""
|
||||||
for inline in self.get_inline_instances(request, obj):
|
for inline in self.get_inline_instances(request, obj):
|
||||||
yield inline.get_formset(request, obj), inline
|
yield inline.get_formset(request, obj), inline
|
||||||
|
@ -861,28 +861,28 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_list_filter(self, request):
|
def get_list_filter(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a sequence containing the fields to be displayed as filters in
|
Return a sequence containing the fields to be displayed as filters in
|
||||||
the right sidebar of the changelist page.
|
the right sidebar of the changelist page.
|
||||||
"""
|
"""
|
||||||
return self.list_filter
|
return self.list_filter
|
||||||
|
|
||||||
def get_list_select_related(self, request):
|
def get_list_select_related(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a list of fields to add to the select_related() part of the
|
Return a list of fields to add to the select_related() part of the
|
||||||
changelist items query.
|
changelist items query.
|
||||||
"""
|
"""
|
||||||
return self.list_select_related
|
return self.list_select_related
|
||||||
|
|
||||||
def get_search_fields(self, request):
|
def get_search_fields(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a sequence containing the fields to be searched whenever
|
Return a sequence containing the fields to be searched whenever
|
||||||
somebody submits a search query.
|
somebody submits a search query.
|
||||||
"""
|
"""
|
||||||
return self.search_fields
|
return self.search_fields
|
||||||
|
|
||||||
def get_search_results(self, request, queryset, search_term):
|
def get_search_results(self, request, queryset, search_term):
|
||||||
"""
|
"""
|
||||||
Returns a tuple containing a queryset to implement the search,
|
Return a tuple containing a queryset to implement the search
|
||||||
and a boolean indicating if the results may contain duplicates.
|
and a boolean indicating if the results may contain duplicates.
|
||||||
"""
|
"""
|
||||||
# Apply keyword searches.
|
# Apply keyword searches.
|
||||||
|
@ -915,7 +915,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_preserved_filters(self, request):
|
def get_preserved_filters(self, request):
|
||||||
"""
|
"""
|
||||||
Returns the preserved filters querystring.
|
Return the preserved filters querystring.
|
||||||
"""
|
"""
|
||||||
match = request.resolver_match
|
match = request.resolver_match
|
||||||
if self.preserve_filters and match:
|
if self.preserve_filters and match:
|
||||||
|
@ -1038,7 +1038,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def response_add(self, request, obj, post_url_continue=None):
|
def response_add(self, request, obj, post_url_continue=None):
|
||||||
"""
|
"""
|
||||||
Determines the HttpResponse for the add_view stage.
|
Determine the HttpResponse for the add_view stage.
|
||||||
"""
|
"""
|
||||||
opts = obj._meta
|
opts = obj._meta
|
||||||
pk_value = obj._get_pk_val()
|
pk_value = obj._get_pk_val()
|
||||||
|
@ -1117,7 +1117,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def response_change(self, request, obj):
|
def response_change(self, request, obj):
|
||||||
"""
|
"""
|
||||||
Determines the HttpResponse for the change_view stage.
|
Determine the HttpResponse for the change_view stage.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if IS_POPUP_VAR in request.POST:
|
if IS_POPUP_VAR in request.POST:
|
||||||
|
@ -1296,9 +1296,8 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def response_delete(self, request, obj_display, obj_id):
|
def response_delete(self, request, obj_display, obj_id):
|
||||||
"""
|
"""
|
||||||
Determines the HttpResponse for the delete_view stage.
|
Determine the HttpResponse for the delete_view stage.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
|
|
||||||
if IS_POPUP_VAR in request.POST:
|
if IS_POPUP_VAR in request.POST:
|
||||||
|
@ -1372,8 +1371,7 @@ class ModelAdmin(BaseModelAdmin):
|
||||||
|
|
||||||
def get_changeform_initial_data(self, request):
|
def get_changeform_initial_data(self, request):
|
||||||
"""
|
"""
|
||||||
Get the initial form data.
|
Get the initial form data from the request's GET params.
|
||||||
Unless overridden, this populates from the GET params.
|
|
||||||
"""
|
"""
|
||||||
initial = dict(request.GET.items())
|
initial = dict(request.GET.items())
|
||||||
for k in initial:
|
for k in initial:
|
||||||
|
@ -1869,7 +1867,7 @@ class InlineModelAdmin(BaseModelAdmin):
|
||||||
return self.max_num
|
return self.max_num
|
||||||
|
|
||||||
def get_formset(self, request, obj=None, **kwargs):
|
def get_formset(self, request, obj=None, **kwargs):
|
||||||
"""Returns a BaseInlineFormSet class for use in admin add/change views."""
|
"""Return a BaseInlineFormSet class for use in admin add/change views."""
|
||||||
if 'fields' in kwargs:
|
if 'fields' in kwargs:
|
||||||
fields = kwargs.pop('fields')
|
fields = kwargs.pop('fields')
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -82,17 +82,17 @@ class AdminSite:
|
||||||
|
|
||||||
def register(self, model_or_iterable, admin_class=None, **options):
|
def register(self, model_or_iterable, admin_class=None, **options):
|
||||||
"""
|
"""
|
||||||
Registers the given model(s) with the given admin class.
|
Register the given model(s) with the given admin class.
|
||||||
|
|
||||||
The model(s) should be Model classes, not instances.
|
The model(s) should be Model classes, not instances.
|
||||||
|
|
||||||
If an admin class isn't given, it will use ModelAdmin (the default
|
If an admin class isn't given, use ModelAdmin (the default admin
|
||||||
admin options). If keyword arguments are given -- e.g., list_display --
|
options). If keyword arguments are given -- e.g., list_display --
|
||||||
they'll be applied as options to the admin class.
|
apply them as options to the admin class.
|
||||||
|
|
||||||
If a model is already registered, this will raise AlreadyRegistered.
|
If a model is already registered, raise AlreadyRegistered.
|
||||||
|
|
||||||
If a model is abstract, this will raise ImproperlyConfigured.
|
If a model is abstract, raise ImproperlyConfigured.
|
||||||
"""
|
"""
|
||||||
if not admin_class:
|
if not admin_class:
|
||||||
admin_class = ModelAdmin
|
admin_class = ModelAdmin
|
||||||
|
@ -125,9 +125,9 @@ class AdminSite:
|
||||||
|
|
||||||
def unregister(self, model_or_iterable):
|
def unregister(self, model_or_iterable):
|
||||||
"""
|
"""
|
||||||
Unregisters the given model(s).
|
Unregister the given model(s).
|
||||||
|
|
||||||
If a model isn't already registered, this will raise NotRegistered.
|
If a model isn't already registered, raise NotRegistered.
|
||||||
"""
|
"""
|
||||||
if isinstance(model_or_iterable, ModelBase):
|
if isinstance(model_or_iterable, ModelBase):
|
||||||
model_or_iterable = [model_or_iterable]
|
model_or_iterable = [model_or_iterable]
|
||||||
|
@ -152,14 +152,14 @@ class AdminSite:
|
||||||
|
|
||||||
def disable_action(self, name):
|
def disable_action(self, name):
|
||||||
"""
|
"""
|
||||||
Disable a globally-registered action. Raises KeyError for invalid names.
|
Disable a globally-registered action. Raise KeyError for invalid names.
|
||||||
"""
|
"""
|
||||||
del self._actions[name]
|
del self._actions[name]
|
||||||
|
|
||||||
def get_action(self, name):
|
def get_action(self, name):
|
||||||
"""
|
"""
|
||||||
Explicitly get a registered global action whether it's enabled or
|
Explicitly get a registered global action whether it's enabled or
|
||||||
not. Raises KeyError for invalid names.
|
not. Raise KeyError for invalid names.
|
||||||
"""
|
"""
|
||||||
return self._global_actions[name]
|
return self._global_actions[name]
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ class AdminSite:
|
||||||
|
|
||||||
def has_permission(self, request):
|
def has_permission(self, request):
|
||||||
"""
|
"""
|
||||||
Returns True if the given HttpRequest has permission to view
|
Return True if the given HttpRequest has permission to view
|
||||||
*at least one* page in the admin site.
|
*at least one* page in the admin site.
|
||||||
"""
|
"""
|
||||||
return request.user.is_active and request.user.is_staff
|
return request.user.is_active and request.user.is_staff
|
||||||
|
@ -280,7 +280,7 @@ class AdminSite:
|
||||||
|
|
||||||
def each_context(self, request):
|
def each_context(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a dictionary of variables to put in the template context for
|
Return a dictionary of variables to put in the template context for
|
||||||
*every* page in the admin site.
|
*every* page in the admin site.
|
||||||
|
|
||||||
For sites running on a subpath, use the SCRIPT_NAME value if site_url
|
For sites running on a subpath, use the SCRIPT_NAME value if site_url
|
||||||
|
@ -298,7 +298,7 @@ class AdminSite:
|
||||||
|
|
||||||
def password_change(self, request, extra_context=None):
|
def password_change(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Handles the "change password" task -- both form display and validation.
|
Handle the "change password" task -- both form display and validation.
|
||||||
"""
|
"""
|
||||||
from django.contrib.admin.forms import AdminPasswordChangeForm
|
from django.contrib.admin.forms import AdminPasswordChangeForm
|
||||||
from django.contrib.auth.views import PasswordChangeView
|
from django.contrib.auth.views import PasswordChangeView
|
||||||
|
@ -315,7 +315,7 @@ class AdminSite:
|
||||||
|
|
||||||
def password_change_done(self, request, extra_context=None):
|
def password_change_done(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Displays the "success" page after a password change.
|
Display the "success" page after a password change.
|
||||||
"""
|
"""
|
||||||
from django.contrib.auth.views import PasswordChangeDoneView
|
from django.contrib.auth.views import PasswordChangeDoneView
|
||||||
defaults = {
|
defaults = {
|
||||||
|
@ -328,7 +328,7 @@ class AdminSite:
|
||||||
|
|
||||||
def i18n_javascript(self, request, extra_context=None):
|
def i18n_javascript(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Displays the i18n JavaScript that the Django admin requires.
|
Display the i18n JavaScript that the Django admin requires.
|
||||||
|
|
||||||
`extra_context` is unused but present for consistency with the other
|
`extra_context` is unused but present for consistency with the other
|
||||||
admin views.
|
admin views.
|
||||||
|
@ -338,7 +338,7 @@ class AdminSite:
|
||||||
@never_cache
|
@never_cache
|
||||||
def logout(self, request, extra_context=None):
|
def logout(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Logs out the user for the given HttpRequest.
|
Log out the user for the given HttpRequest.
|
||||||
|
|
||||||
This should *not* assume the user is already logged in.
|
This should *not* assume the user is already logged in.
|
||||||
"""
|
"""
|
||||||
|
@ -360,7 +360,7 @@ class AdminSite:
|
||||||
@never_cache
|
@never_cache
|
||||||
def login(self, request, extra_context=None):
|
def login(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Displays the login form for the given HttpRequest.
|
Display the login form for the given HttpRequest.
|
||||||
"""
|
"""
|
||||||
if request.method == 'GET' and self.has_permission(request):
|
if request.method == 'GET' and self.has_permission(request):
|
||||||
# Already logged-in, redirect to admin index
|
# Already logged-in, redirect to admin index
|
||||||
|
@ -393,8 +393,8 @@ class AdminSite:
|
||||||
|
|
||||||
def _build_app_dict(self, request, label=None):
|
def _build_app_dict(self, request, label=None):
|
||||||
"""
|
"""
|
||||||
Builds the app dictionary. Takes an optional label parameters to filter
|
Build the app dictionary. The optional `label` parameter filters models
|
||||||
models of a specific app.
|
of a specific app.
|
||||||
"""
|
"""
|
||||||
app_dict = {}
|
app_dict = {}
|
||||||
|
|
||||||
|
@ -458,7 +458,7 @@ class AdminSite:
|
||||||
|
|
||||||
def get_app_list(self, request):
|
def get_app_list(self, request):
|
||||||
"""
|
"""
|
||||||
Returns a sorted list of all the installed apps that have been
|
Return a sorted list of all the installed apps that have been
|
||||||
registered in this site.
|
registered in this site.
|
||||||
"""
|
"""
|
||||||
app_dict = self._build_app_dict(request)
|
app_dict = self._build_app_dict(request)
|
||||||
|
@ -475,7 +475,7 @@ class AdminSite:
|
||||||
@never_cache
|
@never_cache
|
||||||
def index(self, request, extra_context=None):
|
def index(self, request, extra_context=None):
|
||||||
"""
|
"""
|
||||||
Displays the main admin index page, which lists all of the installed
|
Display the main admin index page, which lists all of the installed
|
||||||
apps that have been registered in this site.
|
apps that have been registered in this site.
|
||||||
"""
|
"""
|
||||||
app_list = self.get_app_list(request)
|
app_list = self.get_app_list(request)
|
||||||
|
|
|
@ -29,7 +29,7 @@ DOT = '.'
|
||||||
@register.simple_tag
|
@register.simple_tag
|
||||||
def paginator_number(cl, i):
|
def paginator_number(cl, i):
|
||||||
"""
|
"""
|
||||||
Generates an individual page index link in a paginated list.
|
Generate an individual page index link in a paginated list.
|
||||||
"""
|
"""
|
||||||
if i == DOT:
|
if i == DOT:
|
||||||
return '... '
|
return '... '
|
||||||
|
@ -45,7 +45,7 @@ def paginator_number(cl, i):
|
||||||
@register.inclusion_tag('admin/pagination.html')
|
@register.inclusion_tag('admin/pagination.html')
|
||||||
def pagination(cl):
|
def pagination(cl):
|
||||||
"""
|
"""
|
||||||
Generates the series of links to the pages in a paginated list.
|
Generate the series of links to the pages in a paginated list.
|
||||||
"""
|
"""
|
||||||
paginator, page_num = cl.paginator, cl.page_num
|
paginator, page_num = cl.paginator, cl.page_num
|
||||||
|
|
||||||
|
@ -91,7 +91,7 @@ def pagination(cl):
|
||||||
|
|
||||||
def result_headers(cl):
|
def result_headers(cl):
|
||||||
"""
|
"""
|
||||||
Generates the list column headers.
|
Generate the list column headers.
|
||||||
"""
|
"""
|
||||||
ordering_field_columns = cl.get_ordering_field_columns()
|
ordering_field_columns = cl.get_ordering_field_columns()
|
||||||
for i, field_name in enumerate(cl.list_display):
|
for i, field_name in enumerate(cl.list_display):
|
||||||
|
@ -195,7 +195,7 @@ def _coerce_field_name(field_name, field_index):
|
||||||
|
|
||||||
def items_for_result(cl, result, form):
|
def items_for_result(cl, result, form):
|
||||||
"""
|
"""
|
||||||
Generates the actual list of data.
|
Generate the actual list of data.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def link_in_col(is_first, field_name, cl):
|
def link_in_col(is_first, field_name, cl):
|
||||||
|
@ -285,10 +285,11 @@ def items_for_result(cl, result, form):
|
||||||
|
|
||||||
|
|
||||||
class ResultList(list):
|
class ResultList(list):
|
||||||
# Wrapper class used to return items in a list_editable
|
"""
|
||||||
# changelist, annotated with the form object for error
|
Wrapper class used to return items in a list_editable changelist, annotated
|
||||||
# reporting purposes. Needed to maintain backwards
|
with the form object for error reporting purposes. Needed to maintain
|
||||||
# compatibility with existing admin templates.
|
backwards compatibility with existing admin templates.
|
||||||
|
"""
|
||||||
def __init__(self, form, *items):
|
def __init__(self, form, *items):
|
||||||
self.form = form
|
self.form = form
|
||||||
super().__init__(*items)
|
super().__init__(*items)
|
||||||
|
@ -313,7 +314,7 @@ def result_hidden_fields(cl):
|
||||||
@register.inclusion_tag("admin/change_list_results.html")
|
@register.inclusion_tag("admin/change_list_results.html")
|
||||||
def result_list(cl):
|
def result_list(cl):
|
||||||
"""
|
"""
|
||||||
Displays the headers and data list together
|
Display the headers and data list together.
|
||||||
"""
|
"""
|
||||||
headers = list(result_headers(cl))
|
headers = list(result_headers(cl))
|
||||||
num_sorted_fields = 0
|
num_sorted_fields = 0
|
||||||
|
@ -330,7 +331,7 @@ def result_list(cl):
|
||||||
@register.inclusion_tag('admin/date_hierarchy.html')
|
@register.inclusion_tag('admin/date_hierarchy.html')
|
||||||
def date_hierarchy(cl):
|
def date_hierarchy(cl):
|
||||||
"""
|
"""
|
||||||
Displays the date hierarchy for date drill-down functionality.
|
Display the date hierarchy for date drill-down functionality.
|
||||||
"""
|
"""
|
||||||
if cl.date_hierarchy:
|
if cl.date_hierarchy:
|
||||||
field_name = cl.date_hierarchy
|
field_name = cl.date_hierarchy
|
||||||
|
@ -409,7 +410,7 @@ def date_hierarchy(cl):
|
||||||
@register.inclusion_tag('admin/search_form.html')
|
@register.inclusion_tag('admin/search_form.html')
|
||||||
def search_form(cl):
|
def search_form(cl):
|
||||||
"""
|
"""
|
||||||
Displays a search form for searching the list.
|
Display a search form for searching the list.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'cl': cl,
|
'cl': cl,
|
||||||
|
|
|
@ -9,7 +9,7 @@ register = template.Library()
|
||||||
@register.inclusion_tag('admin/prepopulated_fields_js.html', takes_context=True)
|
@register.inclusion_tag('admin/prepopulated_fields_js.html', takes_context=True)
|
||||||
def prepopulated_fields_js(context):
|
def prepopulated_fields_js(context):
|
||||||
"""
|
"""
|
||||||
Creates a list of prepopulated_fields that should render Javascript for
|
Create a list of prepopulated_fields that should render Javascript for
|
||||||
the prepopulated fields for both the admin form and inlines.
|
the prepopulated fields for both the admin form and inlines.
|
||||||
"""
|
"""
|
||||||
prepopulated_fields = []
|
prepopulated_fields = []
|
||||||
|
@ -42,7 +42,7 @@ def prepopulated_fields_js(context):
|
||||||
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
|
@register.inclusion_tag('admin/submit_line.html', takes_context=True)
|
||||||
def submit_row(context):
|
def submit_row(context):
|
||||||
"""
|
"""
|
||||||
Displays the row of buttons for delete and save.
|
Display the row of buttons for delete and save.
|
||||||
"""
|
"""
|
||||||
change = context['change']
|
change = context['change']
|
||||||
is_popup = context['is_popup']
|
is_popup = context['is_popup']
|
||||||
|
@ -68,7 +68,7 @@ def submit_row(context):
|
||||||
|
|
||||||
@register.filter
|
@register.filter
|
||||||
def cell_count(inline_admin_form):
|
def cell_count(inline_admin_form):
|
||||||
"""Returns the number of cells used in a tabular inline"""
|
"""Return the number of cells used in a tabular inline."""
|
||||||
count = 1 # Hidden cell with hidden 'id' field
|
count = 1 # Hidden cell with hidden 'id' field
|
||||||
for fieldset in inline_admin_form:
|
for fieldset in inline_admin_form:
|
||||||
# Loop through all the fields (one per cell)
|
# Loop through all the fields (one per cell)
|
||||||
|
|
|
@ -26,7 +26,7 @@ class AdminLogNode(template.Node):
|
||||||
@register.tag
|
@register.tag
|
||||||
def get_admin_log(parser, token):
|
def get_admin_log(parser, token):
|
||||||
"""
|
"""
|
||||||
Populates a template variable with the admin log for the given criteria.
|
Populate a template variable with the admin log for the given criteria.
|
||||||
|
|
||||||
Usage::
|
Usage::
|
||||||
|
|
||||||
|
|
|
@ -25,10 +25,10 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def wait_until(self, callback, timeout=10):
|
def wait_until(self, callback, timeout=10):
|
||||||
"""
|
"""
|
||||||
Helper function that blocks the execution of the tests until the
|
Block the execution of the tests until the specified callback returns a
|
||||||
specified callback returns a value that is not falsy. This function can
|
value that is not falsy. This method can be called, for example, after
|
||||||
be called, for example, after clicking a link or submitting a form.
|
clicking a link or submitting a form. See the other public methods that
|
||||||
See the other public methods that call this function for more details.
|
call this function for more details.
|
||||||
"""
|
"""
|
||||||
from selenium.webdriver.support.wait import WebDriverWait
|
from selenium.webdriver.support.wait import WebDriverWait
|
||||||
WebDriverWait(self.selenium, timeout).until(callback)
|
WebDriverWait(self.selenium, timeout).until(callback)
|
||||||
|
@ -42,7 +42,7 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def wait_for(self, css_selector, timeout=10):
|
def wait_for(self, css_selector, timeout=10):
|
||||||
"""
|
"""
|
||||||
Helper function that blocks until a CSS selector is found on the page.
|
Block until a CSS selector is found on the page.
|
||||||
"""
|
"""
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support import expected_conditions as ec
|
from selenium.webdriver.support import expected_conditions as ec
|
||||||
|
@ -53,7 +53,7 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def wait_for_text(self, css_selector, text, timeout=10):
|
def wait_for_text(self, css_selector, text, timeout=10):
|
||||||
"""
|
"""
|
||||||
Helper function that blocks until the text is found in the CSS selector.
|
Block until the text is found in the CSS selector.
|
||||||
"""
|
"""
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support import expected_conditions as ec
|
from selenium.webdriver.support import expected_conditions as ec
|
||||||
|
@ -65,7 +65,7 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def wait_for_value(self, css_selector, text, timeout=10):
|
def wait_for_value(self, css_selector, text, timeout=10):
|
||||||
"""
|
"""
|
||||||
Helper function that blocks until the value is found in the CSS selector.
|
Block until the value is found in the CSS selector.
|
||||||
"""
|
"""
|
||||||
from selenium.webdriver.common.by import By
|
from selenium.webdriver.common.by import By
|
||||||
from selenium.webdriver.support import expected_conditions as ec
|
from selenium.webdriver.support import expected_conditions as ec
|
||||||
|
@ -113,7 +113,7 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def admin_login(self, username, password, login_url='/admin/'):
|
def admin_login(self, username, password, login_url='/admin/'):
|
||||||
"""
|
"""
|
||||||
Helper function to log into the admin.
|
Log in to the admin.
|
||||||
"""
|
"""
|
||||||
self.selenium.get('%s%s' % (self.live_server_url, login_url))
|
self.selenium.get('%s%s' % (self.live_server_url, login_url))
|
||||||
username_input = self.selenium.find_element_by_name('username')
|
username_input = self.selenium.find_element_by_name('username')
|
||||||
|
@ -127,16 +127,15 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def get_css_value(self, selector, attribute):
|
def get_css_value(self, selector, attribute):
|
||||||
"""
|
"""
|
||||||
Helper function that returns the value for the CSS attribute of an
|
Return the value for the CSS attribute of a DOM element specified by
|
||||||
DOM element specified by the given selector. Uses the jQuery that ships
|
the given selector. Uses the jQuery that ships with Django.
|
||||||
with Django.
|
|
||||||
"""
|
"""
|
||||||
return self.selenium.execute_script(
|
return self.selenium.execute_script(
|
||||||
'return django.jQuery("%s").css("%s")' % (selector, attribute))
|
'return django.jQuery("%s").css("%s")' % (selector, attribute))
|
||||||
|
|
||||||
def get_select_option(self, selector, value):
|
def get_select_option(self, selector, value):
|
||||||
"""
|
"""
|
||||||
Returns the <OPTION> with the value `value` inside the <SELECT> widget
|
Return the <OPTION> with the value `value` inside the <SELECT> widget
|
||||||
identified by the CSS selector `selector`.
|
identified by the CSS selector `selector`.
|
||||||
"""
|
"""
|
||||||
from selenium.common.exceptions import NoSuchElementException
|
from selenium.common.exceptions import NoSuchElementException
|
||||||
|
@ -164,21 +163,21 @@ class AdminSeleniumTestCase(SeleniumTestCase, StaticLiveServerTestCase):
|
||||||
|
|
||||||
def assertSelectOptions(self, selector, values):
|
def assertSelectOptions(self, selector, values):
|
||||||
"""
|
"""
|
||||||
Asserts that the <SELECT> widget identified by `selector` has the
|
Assert that the <SELECT> widget identified by `selector` has the
|
||||||
options with the given `values`.
|
options with the given `values`.
|
||||||
"""
|
"""
|
||||||
self._assertOptionsValues("%s > option" % selector, values)
|
self._assertOptionsValues("%s > option" % selector, values)
|
||||||
|
|
||||||
def assertSelectedOptions(self, selector, values):
|
def assertSelectedOptions(self, selector, values):
|
||||||
"""
|
"""
|
||||||
Asserts that the <SELECT> widget identified by `selector` has the
|
Assert that the <SELECT> widget identified by `selector` has the
|
||||||
selected options with the given `values`.
|
selected options with the given `values`.
|
||||||
"""
|
"""
|
||||||
self._assertOptionsValues("%s > option:checked" % selector, values)
|
self._assertOptionsValues("%s > option:checked" % selector, values)
|
||||||
|
|
||||||
def has_css_class(self, selector, klass):
|
def has_css_class(self, selector, klass):
|
||||||
"""
|
"""
|
||||||
Returns True if the element identified by `selector` has the CSS class
|
Return True if the element identified by `selector` has the CSS class
|
||||||
`klass`.
|
`klass`.
|
||||||
"""
|
"""
|
||||||
return (self.selenium.find_element_by_css_selector(selector)
|
return (self.selenium.find_element_by_css_selector(selector)
|
||||||
|
|
|
@ -26,7 +26,7 @@ class FieldIsAForeignKeyColumnName(Exception):
|
||||||
|
|
||||||
def lookup_needs_distinct(opts, lookup_path):
|
def lookup_needs_distinct(opts, lookup_path):
|
||||||
"""
|
"""
|
||||||
Returns True if 'distinct()' should be used to query the given lookup path.
|
Return True if 'distinct()' should be used to query the given lookup path.
|
||||||
"""
|
"""
|
||||||
lookup_fields = lookup_path.split(LOOKUP_SEP)
|
lookup_fields = lookup_path.split(LOOKUP_SEP)
|
||||||
# Remove the last item of the lookup path if it is a query term
|
# Remove the last item of the lookup path if it is a query term
|
||||||
|
@ -47,7 +47,7 @@ def lookup_needs_distinct(opts, lookup_path):
|
||||||
|
|
||||||
def prepare_lookup_value(key, value):
|
def prepare_lookup_value(key, value):
|
||||||
"""
|
"""
|
||||||
Returns a lookup value prepared to be used in queryset filtering.
|
Return a lookup value prepared to be used in queryset filtering.
|
||||||
"""
|
"""
|
||||||
# if key ends with __in, split parameter into separate values
|
# if key ends with __in, split parameter into separate values
|
||||||
if key.endswith('__in'):
|
if key.endswith('__in'):
|
||||||
|
@ -100,8 +100,9 @@ def unquote(s):
|
||||||
|
|
||||||
|
|
||||||
def flatten(fields):
|
def flatten(fields):
|
||||||
"""Returns a list which is a single level of flattening of the
|
"""
|
||||||
original list."""
|
Return a list which is a single level of flattening of the original list.
|
||||||
|
"""
|
||||||
flat = []
|
flat = []
|
||||||
for field in fields:
|
for field in fields:
|
||||||
if isinstance(field, (list, tuple)):
|
if isinstance(field, (list, tuple)):
|
||||||
|
@ -112,7 +113,7 @@ def flatten(fields):
|
||||||
|
|
||||||
|
|
||||||
def flatten_fieldsets(fieldsets):
|
def flatten_fieldsets(fieldsets):
|
||||||
"""Returns a list of field names from an admin fieldsets structure."""
|
"""Return a list of field names from an admin fieldsets structure."""
|
||||||
field_names = []
|
field_names = []
|
||||||
for name, opts in fieldsets:
|
for name, opts in fieldsets:
|
||||||
field_names.extend(
|
field_names.extend(
|
||||||
|
@ -126,7 +127,7 @@ def get_deleted_objects(objs, opts, user, admin_site, using):
|
||||||
Find all objects related to ``objs`` that should also be deleted. ``objs``
|
Find all objects related to ``objs`` that should also be deleted. ``objs``
|
||||||
must be a homogeneous iterable of objects (e.g. a QuerySet).
|
must be a homogeneous iterable of objects (e.g. a QuerySet).
|
||||||
|
|
||||||
Returns a nested list of strings suitable for display in the
|
Return a nested list of strings suitable for display in the
|
||||||
template with the ``unordered_list`` filter.
|
template with the ``unordered_list`` filter.
|
||||||
"""
|
"""
|
||||||
collector = NestedObjects(using=using)
|
collector = NestedObjects(using=using)
|
||||||
|
@ -322,11 +323,11 @@ def _get_non_gfk_field(opts, name):
|
||||||
|
|
||||||
def label_for_field(name, model, model_admin=None, return_attr=False):
|
def label_for_field(name, model, model_admin=None, return_attr=False):
|
||||||
"""
|
"""
|
||||||
Returns a sensible label for a field name. The name can be a callable,
|
Return a sensible label for a field name. The name can be a callable,
|
||||||
property (but not created with @property decorator) or the name of an
|
property (but not created with @property decorator), or the name of an
|
||||||
object's attribute, as well as a genuine fields. If return_attr is
|
object's attribute, as well as a model field. If return_attr is True, also
|
||||||
True, the resolved attribute (which could be a callable) is also returned.
|
return the resolved attribute (which could be a callable). This will be
|
||||||
This will be None if (and only if) the name refers to a field.
|
None if (and only if) the name refers to a field.
|
||||||
"""
|
"""
|
||||||
attr = None
|
attr = None
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -84,7 +84,7 @@ class ChangeList:
|
||||||
|
|
||||||
def get_filters_params(self, params=None):
|
def get_filters_params(self, params=None):
|
||||||
"""
|
"""
|
||||||
Returns all params except IGNORED_PARAMS
|
Return all params except IGNORED_PARAMS.
|
||||||
"""
|
"""
|
||||||
if not params:
|
if not params:
|
||||||
params = self.params
|
params = self.params
|
||||||
|
@ -212,10 +212,10 @@ class ChangeList:
|
||||||
|
|
||||||
def get_ordering_field(self, field_name):
|
def get_ordering_field(self, field_name):
|
||||||
"""
|
"""
|
||||||
Returns the proper model field name corresponding to the given
|
Return the proper model field name corresponding to the given
|
||||||
field_name to use for ordering. field_name may either be the name of a
|
field_name to use for ordering. field_name may either be the name of a
|
||||||
proper model field or the name of a method (on the admin or model) or a
|
proper model field or the name of a method (on the admin or model) or a
|
||||||
callable with the 'admin_order_field' attribute. Returns None if no
|
callable with the 'admin_order_field' attribute. Return None if no
|
||||||
proper model field name can be matched.
|
proper model field name can be matched.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -234,8 +234,8 @@ class ChangeList:
|
||||||
|
|
||||||
def get_ordering(self, request, queryset):
|
def get_ordering(self, request, queryset):
|
||||||
"""
|
"""
|
||||||
Returns the list of ordering fields for the change list.
|
Return the list of ordering fields for the change list.
|
||||||
First we check the get_ordering() method in model admin, then we check
|
First check the get_ordering() method in model admin, then check
|
||||||
the object's default ordering. Then, any manually-specified ordering
|
the object's default ordering. Then, any manually-specified ordering
|
||||||
from the query string overrides anything. Finally, a deterministic
|
from the query string overrides anything. Finally, a deterministic
|
||||||
order is guaranteed by ensuring the primary key is used as the last
|
order is guaranteed by ensuring the primary key is used as the last
|
||||||
|
@ -278,9 +278,8 @@ class ChangeList:
|
||||||
|
|
||||||
def get_ordering_field_columns(self):
|
def get_ordering_field_columns(self):
|
||||||
"""
|
"""
|
||||||
Returns an OrderedDict of ordering field column numbers and asc/desc
|
Return an OrderedDict of ordering field column numbers and asc/desc.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# We must cope with more than one column having the same underlying sort
|
# We must cope with more than one column having the same underlying sort
|
||||||
# field, so we base things on column numbers.
|
# field, so we base things on column numbers.
|
||||||
ordering = self._get_default_ordering()
|
ordering = self._get_default_ordering()
|
||||||
|
|
|
@ -96,7 +96,7 @@ class AdminFileWidget(forms.ClearableFileInput):
|
||||||
|
|
||||||
def url_params_from_lookup_dict(lookups):
|
def url_params_from_lookup_dict(lookups):
|
||||||
"""
|
"""
|
||||||
Converts the type of lookups specified in a ForeignKey limit_choices_to
|
Convert the type of lookups specified in a ForeignKey limit_choices_to
|
||||||
attribute to a dictionary of query parameters
|
attribute to a dictionary of query parameters
|
||||||
"""
|
"""
|
||||||
params = {}
|
params = {}
|
||||||
|
|
|
@ -5,14 +5,14 @@ from django.utils.deprecation import MiddlewareMixin
|
||||||
|
|
||||||
class XViewMiddleware(MiddlewareMixin):
|
class XViewMiddleware(MiddlewareMixin):
|
||||||
"""
|
"""
|
||||||
Adds an X-View header to internal HEAD requests -- used by the documentation system.
|
Add an X-View header to internal HEAD requests.
|
||||||
"""
|
"""
|
||||||
def process_view(self, request, view_func, view_args, view_kwargs):
|
def process_view(self, request, view_func, view_args, view_kwargs):
|
||||||
"""
|
"""
|
||||||
If the request method is HEAD and either the IP is internal or the
|
If the request method is HEAD and either the IP is internal or the
|
||||||
user is a logged-in staff member, quickly return with an x-header
|
user is a logged-in staff member, return a responsewith an x-view
|
||||||
indicating the view function. This is used by the documentation module
|
header indicating the view function. This is used to lookup the view
|
||||||
to lookup the view function for an arbitrary page.
|
function for an arbitrary page.
|
||||||
"""
|
"""
|
||||||
assert hasattr(request, 'user'), (
|
assert hasattr(request, 'user'), (
|
||||||
"The XView middleware requires authentication middleware to be "
|
"The XView middleware requires authentication middleware to be "
|
||||||
|
|
|
@ -385,10 +385,11 @@ def get_return_data_type(func_name):
|
||||||
|
|
||||||
|
|
||||||
def get_readable_field_data_type(field):
|
def get_readable_field_data_type(field):
|
||||||
"""Returns the description for a given field type, if it exists,
|
"""
|
||||||
Fields' descriptions can contain format strings, which will be interpolated
|
Return the description for a given field type, if it exists. Fields'
|
||||||
against the values of field.__dict__ before being output."""
|
descriptions can contain format strings, which will be interpolated with
|
||||||
|
the values of field.__dict__ before being output.
|
||||||
|
"""
|
||||||
return field.description % field.__dict__
|
return field.description % field.__dict__
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -42,7 +42,7 @@ def get_backends():
|
||||||
|
|
||||||
def _clean_credentials(credentials):
|
def _clean_credentials(credentials):
|
||||||
"""
|
"""
|
||||||
Cleans a dictionary of credentials of potentially sensitive info before
|
Clean a dictionary of credentials of potentially sensitive info before
|
||||||
sending to less secure functions.
|
sending to less secure functions.
|
||||||
|
|
||||||
Not comprehensive - intended for user_login_failed signal
|
Not comprehensive - intended for user_login_failed signal
|
||||||
|
@ -144,8 +144,8 @@ def login(request, user, backend=None):
|
||||||
|
|
||||||
def logout(request):
|
def logout(request):
|
||||||
"""
|
"""
|
||||||
Removes the authenticated user's ID from the request and flushes their
|
Remove the authenticated user's ID from the request and flush their session
|
||||||
session data.
|
data.
|
||||||
"""
|
"""
|
||||||
# Dispatch the signal before the user is logged out so the receivers have a
|
# Dispatch the signal before the user is logged out so the receivers have a
|
||||||
# chance to find out *who* logged out.
|
# chance to find out *who* logged out.
|
||||||
|
@ -169,7 +169,7 @@ def logout(request):
|
||||||
|
|
||||||
def get_user_model():
|
def get_user_model():
|
||||||
"""
|
"""
|
||||||
Returns the User model that is active in this project.
|
Return the User model that is active in this project.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
|
return django_apps.get_model(settings.AUTH_USER_MODEL, require_ready=False)
|
||||||
|
@ -183,8 +183,8 @@ def get_user_model():
|
||||||
|
|
||||||
def get_user(request):
|
def get_user(request):
|
||||||
"""
|
"""
|
||||||
Returns the user model instance associated with the given request session.
|
Return the user model instance associated with the given request session.
|
||||||
If no user is retrieved an instance of `AnonymousUser` is returned.
|
If no user is retrieved, return an instance of `AnonymousUser`.
|
||||||
"""
|
"""
|
||||||
from .models import AnonymousUser
|
from .models import AnonymousUser
|
||||||
user = None
|
user = None
|
||||||
|
@ -213,7 +213,7 @@ def get_user(request):
|
||||||
|
|
||||||
def get_permission_codename(action, opts):
|
def get_permission_codename(action, opts):
|
||||||
"""
|
"""
|
||||||
Returns the codename of the permission for the specified action.
|
Return the codename of the permission for the specified action.
|
||||||
"""
|
"""
|
||||||
return '%s_%s' % (action, opts.model_name)
|
return '%s_%s' % (action, opts.model_name)
|
||||||
|
|
||||||
|
@ -222,10 +222,10 @@ def update_session_auth_hash(request, user):
|
||||||
"""
|
"""
|
||||||
Updating a user's password logs out all sessions for the user.
|
Updating a user's password logs out all sessions for the user.
|
||||||
|
|
||||||
This function takes the current request and the updated user object from
|
Take the current request and the updated user object from which the new
|
||||||
which the new session hash will be derived and updates the session hash
|
session hash will be derived and update the session hash appropriately to
|
||||||
appropriately to prevent a password change from logging out the session
|
prevent a password change from logging out the session from which the
|
||||||
from which the password was changed.
|
password was changed.
|
||||||
"""
|
"""
|
||||||
request.session.cycle_key()
|
request.session.cycle_key()
|
||||||
if hasattr(user, 'get_session_auth_hash') and request.user == user:
|
if hasattr(user, 'get_session_auth_hash') and request.user == user:
|
||||||
|
|
|
@ -193,7 +193,7 @@ class UserAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
def response_add(self, request, obj, post_url_continue=None):
|
def response_add(self, request, obj, post_url_continue=None):
|
||||||
"""
|
"""
|
||||||
Determines the HttpResponse for the add_view stage. It mostly defers to
|
Determine the HttpResponse for the add_view stage. It mostly defers to
|
||||||
its superclass implementation but is customized because the User model
|
its superclass implementation but is customized because the User model
|
||||||
has a slightly different workflow.
|
has a slightly different workflow.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -40,7 +40,7 @@ class ModelBackend:
|
||||||
|
|
||||||
def _get_permissions(self, user_obj, obj, from_name):
|
def _get_permissions(self, user_obj, obj, from_name):
|
||||||
"""
|
"""
|
||||||
Returns the permissions of `user_obj` from `from_name`. `from_name` can
|
Return the permissions of `user_obj` from `from_name`. `from_name` can
|
||||||
be either "group" or "user" to return permissions from
|
be either "group" or "user" to return permissions from
|
||||||
`_get_group_permissions` or `_get_user_permissions` respectively.
|
`_get_group_permissions` or `_get_user_permissions` respectively.
|
||||||
"""
|
"""
|
||||||
|
@ -59,14 +59,14 @@ class ModelBackend:
|
||||||
|
|
||||||
def get_user_permissions(self, user_obj, obj=None):
|
def get_user_permissions(self, user_obj, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns a set of permission strings the user `user_obj` has from their
|
Return a set of permission strings the user `user_obj` has from their
|
||||||
`user_permissions`.
|
`user_permissions`.
|
||||||
"""
|
"""
|
||||||
return self._get_permissions(user_obj, obj, 'user')
|
return self._get_permissions(user_obj, obj, 'user')
|
||||||
|
|
||||||
def get_group_permissions(self, user_obj, obj=None):
|
def get_group_permissions(self, user_obj, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns a set of permission strings the user `user_obj` has from the
|
Return a set of permission strings the user `user_obj` has from the
|
||||||
groups they belong.
|
groups they belong.
|
||||||
"""
|
"""
|
||||||
return self._get_permissions(user_obj, obj, 'group')
|
return self._get_permissions(user_obj, obj, 'group')
|
||||||
|
@ -86,7 +86,7 @@ class ModelBackend:
|
||||||
|
|
||||||
def has_module_perms(self, user_obj, app_label):
|
def has_module_perms(self, user_obj, app_label):
|
||||||
"""
|
"""
|
||||||
Returns True if user_obj has any permissions in the given app_label.
|
Return True if user_obj has any permissions in the given app_label.
|
||||||
"""
|
"""
|
||||||
if not user_obj.is_active:
|
if not user_obj.is_active:
|
||||||
return False
|
return False
|
||||||
|
@ -125,11 +125,11 @@ class RemoteUserBackend(ModelBackend):
|
||||||
|
|
||||||
def authenticate(self, request, remote_user):
|
def authenticate(self, request, remote_user):
|
||||||
"""
|
"""
|
||||||
The username passed as ``remote_user`` is considered trusted. This
|
The username passed as ``remote_user`` is considered trusted. Return
|
||||||
method simply returns the ``User`` object with the given username,
|
the ``User`` object with the given username. Create a new ``User``
|
||||||
creating a new ``User`` object if ``create_unknown_user`` is ``True``.
|
object if ``create_unknown_user`` is ``True``.
|
||||||
|
|
||||||
Returns None if ``create_unknown_user`` is ``False`` and a ``User``
|
Return None if ``create_unknown_user`` is ``False`` and a ``User``
|
||||||
object with the given username is not found in the database.
|
object with the given username is not found in the database.
|
||||||
"""
|
"""
|
||||||
if not remote_user:
|
if not remote_user:
|
||||||
|
@ -155,18 +155,18 @@ class RemoteUserBackend(ModelBackend):
|
||||||
|
|
||||||
def clean_username(self, username):
|
def clean_username(self, username):
|
||||||
"""
|
"""
|
||||||
Performs any cleaning on the "username" prior to using it to get or
|
Perform any cleaning on the "username" prior to using it to get or
|
||||||
create the user object. Returns the cleaned username.
|
create the user object. Return the cleaned username.
|
||||||
|
|
||||||
By default, returns the username unchanged.
|
By default, return the username unchanged.
|
||||||
"""
|
"""
|
||||||
return username
|
return username
|
||||||
|
|
||||||
def configure_user(self, user):
|
def configure_user(self, user):
|
||||||
"""
|
"""
|
||||||
Configures a user after creation and returns the updated user.
|
Configure a user after creation and return the updated user.
|
||||||
|
|
||||||
By default, returns the user unmodified.
|
By default, return the user unmodified.
|
||||||
"""
|
"""
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
|
@ -45,10 +45,10 @@ class PermWrapper:
|
||||||
|
|
||||||
def auth(request):
|
def auth(request):
|
||||||
"""
|
"""
|
||||||
Returns context variables required by apps that use Django's authentication
|
Return context variables required by apps that use Django's authentication
|
||||||
system.
|
system.
|
||||||
|
|
||||||
If there is no 'user' attribute in the request, uses AnonymousUser (from
|
If there is no 'user' attribute in the request, use AnonymousUser (from
|
||||||
django.contrib.auth).
|
django.contrib.auth).
|
||||||
"""
|
"""
|
||||||
if hasattr(request, 'user'):
|
if hasattr(request, 'user'):
|
||||||
|
|
|
@ -226,7 +226,7 @@ class PasswordResetForm(forms.Form):
|
||||||
def send_mail(self, subject_template_name, email_template_name,
|
def send_mail(self, subject_template_name, email_template_name,
|
||||||
context, from_email, to_email, html_email_template_name=None):
|
context, from_email, to_email, html_email_template_name=None):
|
||||||
"""
|
"""
|
||||||
Sends a django.core.mail.EmailMultiAlternatives to `to_email`.
|
Send a django.core.mail.EmailMultiAlternatives to `to_email`.
|
||||||
"""
|
"""
|
||||||
subject = loader.render_to_string(subject_template_name, context)
|
subject = loader.render_to_string(subject_template_name, context)
|
||||||
# Email subject *must not* contain newlines
|
# Email subject *must not* contain newlines
|
||||||
|
@ -260,7 +260,7 @@ class PasswordResetForm(forms.Form):
|
||||||
from_email=None, request=None, html_email_template_name=None,
|
from_email=None, request=None, html_email_template_name=None,
|
||||||
extra_email_context=None):
|
extra_email_context=None):
|
||||||
"""
|
"""
|
||||||
Generates a one-use only link for resetting password and sends to the
|
Generate a one-use only link for resetting password and send it to the
|
||||||
user.
|
user.
|
||||||
"""
|
"""
|
||||||
email = self.cleaned_data["email"]
|
email = self.cleaned_data["email"]
|
||||||
|
@ -350,7 +350,7 @@ class PasswordChangeForm(SetPasswordForm):
|
||||||
|
|
||||||
def clean_old_password(self):
|
def clean_old_password(self):
|
||||||
"""
|
"""
|
||||||
Validates that the old_password field is correct.
|
Validate that the old_password field is correct.
|
||||||
"""
|
"""
|
||||||
old_password = self.cleaned_data["old_password"]
|
old_password = self.cleaned_data["old_password"]
|
||||||
if not self.user.check_password(old_password):
|
if not self.user.check_password(old_password):
|
||||||
|
@ -399,9 +399,7 @@ class AdminPasswordChangeForm(forms.Form):
|
||||||
return password2
|
return password2
|
||||||
|
|
||||||
def save(self, commit=True):
|
def save(self, commit=True):
|
||||||
"""
|
"""Save the new password."""
|
||||||
Saves the new password.
|
|
||||||
"""
|
|
||||||
password = self.cleaned_data["password1"]
|
password = self.cleaned_data["password1"]
|
||||||
self.user.set_password(password)
|
self.user.set_password(password)
|
||||||
if commit:
|
if commit:
|
||||||
|
|
|
@ -7,16 +7,14 @@ UserModel = auth.get_user_model()
|
||||||
|
|
||||||
def check_password(environ, username, password):
|
def check_password(environ, username, password):
|
||||||
"""
|
"""
|
||||||
Authenticates against Django's auth database
|
Authenticate against Django's auth database.
|
||||||
|
|
||||||
mod_wsgi docs specify None, True, False as return value depending
|
mod_wsgi docs specify None, True, False as return value depending
|
||||||
on whether the user exists and authenticates.
|
on whether the user exists and authenticates.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# db connection state is managed similarly to the wsgi handler
|
# db connection state is managed similarly to the wsgi handler
|
||||||
# as mod_wsgi may call these functions outside of a request/response cycle
|
# as mod_wsgi may call these functions outside of a request/response cycle
|
||||||
db.reset_queries()
|
db.reset_queries()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
user = UserModel._default_manager.get_by_natural_key(username)
|
user = UserModel._default_manager.get_by_natural_key(username)
|
||||||
|
@ -31,11 +29,9 @@ def check_password(environ, username, password):
|
||||||
|
|
||||||
def groups_for_user(environ, username):
|
def groups_for_user(environ, username):
|
||||||
"""
|
"""
|
||||||
Authorizes a user based on groups
|
Authorize a user based on groups
|
||||||
"""
|
"""
|
||||||
|
|
||||||
db.reset_queries()
|
db.reset_queries()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
user = UserModel._default_manager.get_by_natural_key(username)
|
user = UserModel._default_manager.get_by_natural_key(username)
|
||||||
|
|
|
@ -33,7 +33,7 @@ def is_password_usable(encoded):
|
||||||
|
|
||||||
def check_password(password, encoded, setter=None, preferred='default'):
|
def check_password(password, encoded, setter=None, preferred='default'):
|
||||||
"""
|
"""
|
||||||
Returns a boolean of whether the raw password matches the three
|
Return a boolean of whether the raw password matches the three
|
||||||
part encoded digest.
|
part encoded digest.
|
||||||
|
|
||||||
If setter is specified, it'll be called when you need to
|
If setter is specified, it'll be called when you need to
|
||||||
|
@ -65,12 +65,10 @@ def make_password(password, salt=None, hasher='default'):
|
||||||
"""
|
"""
|
||||||
Turn a plain-text password into a hash for database storage
|
Turn a plain-text password into a hash for database storage
|
||||||
|
|
||||||
Same as encode() but generates a new random salt.
|
Same as encode() but generate a new random salt. If password is None then
|
||||||
If password is None then a concatenation of
|
return a concatenation of UNUSABLE_PASSWORD_PREFIX and a random string,
|
||||||
UNUSABLE_PASSWORD_PREFIX and a random string will be returned
|
which disallows logins. Additional random string reduces chances of gaining
|
||||||
which disallows logins. Additional random string reduces chances
|
access to staff or superuser accounts. See ticket #20079 for more info.
|
||||||
of gaining access to staff or superuser accounts.
|
|
||||||
See ticket #20079 for more info.
|
|
||||||
"""
|
"""
|
||||||
if password is None:
|
if password is None:
|
||||||
return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
|
return UNUSABLE_PASSWORD_PREFIX + get_random_string(UNUSABLE_PASSWORD_SUFFIX_LENGTH)
|
||||||
|
@ -109,11 +107,10 @@ def reset_hashers(**kwargs):
|
||||||
|
|
||||||
def get_hasher(algorithm='default'):
|
def get_hasher(algorithm='default'):
|
||||||
"""
|
"""
|
||||||
Returns an instance of a loaded password hasher.
|
Return an instance of a loaded password hasher.
|
||||||
|
|
||||||
If algorithm is 'default', the default hasher will be returned.
|
If algorithm is 'default', return the default hasher. Lazily import hashers
|
||||||
This function will also lazy import hashers specified in your
|
specified in the project's settings file if needed.
|
||||||
settings file if needed.
|
|
||||||
"""
|
"""
|
||||||
if hasattr(algorithm, 'algorithm'):
|
if hasattr(algorithm, 'algorithm'):
|
||||||
return algorithm
|
return algorithm
|
||||||
|
@ -133,10 +130,10 @@ def get_hasher(algorithm='default'):
|
||||||
|
|
||||||
def identify_hasher(encoded):
|
def identify_hasher(encoded):
|
||||||
"""
|
"""
|
||||||
Returns an instance of a loaded password hasher.
|
Return an instance of a loaded password hasher.
|
||||||
|
|
||||||
Identifies hasher algorithm by examining encoded hash, and calls
|
Identify hasher algorithm by examining encoded hash, and call
|
||||||
get_hasher() to return hasher. Raises ValueError if
|
get_hasher() to return hasher. Raise ValueError if
|
||||||
algorithm cannot be identified, or if hasher is not loaded.
|
algorithm cannot be identified, or if hasher is not loaded.
|
||||||
"""
|
"""
|
||||||
# Ancient versions of Django created plain MD5 passwords and accepted
|
# Ancient versions of Django created plain MD5 passwords and accepted
|
||||||
|
@ -154,7 +151,7 @@ def identify_hasher(encoded):
|
||||||
|
|
||||||
def mask_hash(hash, show=6, char="*"):
|
def mask_hash(hash, show=6, char="*"):
|
||||||
"""
|
"""
|
||||||
Returns the given hash, with only the first ``show`` number shown. The
|
Return the given hash, with only the first ``show`` number shown. The
|
||||||
rest are masked with ``char`` for security reasons.
|
rest are masked with ``char`` for security reasons.
|
||||||
"""
|
"""
|
||||||
masked = hash[:show]
|
masked = hash[:show]
|
||||||
|
@ -190,20 +187,16 @@ class BasePasswordHasher:
|
||||||
self.__class__.__name__)
|
self.__class__.__name__)
|
||||||
|
|
||||||
def salt(self):
|
def salt(self):
|
||||||
"""
|
"""Generate a cryptographically secure nonce salt in ASCII."""
|
||||||
Generates a cryptographically secure nonce salt in ASCII
|
|
||||||
"""
|
|
||||||
return get_random_string()
|
return get_random_string()
|
||||||
|
|
||||||
def verify(self, password, encoded):
|
def verify(self, password, encoded):
|
||||||
"""
|
"""Check if the given password is correct."""
|
||||||
Checks if the given password is correct
|
|
||||||
"""
|
|
||||||
raise NotImplementedError('subclasses of BasePasswordHasher must provide a verify() method')
|
raise NotImplementedError('subclasses of BasePasswordHasher must provide a verify() method')
|
||||||
|
|
||||||
def encode(self, password, salt):
|
def encode(self, password, salt):
|
||||||
"""
|
"""
|
||||||
Creates an encoded database value
|
Create an encoded database value.
|
||||||
|
|
||||||
The result is normally formatted as "algorithm$salt$hash" and
|
The result is normally formatted as "algorithm$salt$hash" and
|
||||||
must be fewer than 128 characters.
|
must be fewer than 128 characters.
|
||||||
|
@ -212,7 +205,7 @@ class BasePasswordHasher:
|
||||||
|
|
||||||
def safe_summary(self, encoded):
|
def safe_summary(self, encoded):
|
||||||
"""
|
"""
|
||||||
Returns a summary of safe values
|
Return a summary of safe values.
|
||||||
|
|
||||||
The result is a dictionary and will be used where the password field
|
The result is a dictionary and will be used where the password field
|
||||||
must be displayed to construct a safe representation of the password.
|
must be displayed to construct a safe representation of the password.
|
||||||
|
@ -542,7 +535,7 @@ class MD5PasswordHasher(BasePasswordHasher):
|
||||||
|
|
||||||
class UnsaltedSHA1PasswordHasher(BasePasswordHasher):
|
class UnsaltedSHA1PasswordHasher(BasePasswordHasher):
|
||||||
"""
|
"""
|
||||||
Very insecure algorithm that you should *never* use; stores SHA1 hashes
|
Very insecure algorithm that you should *never* use; store SHA1 hashes
|
||||||
with an empty salt.
|
with an empty salt.
|
||||||
|
|
||||||
This class is implemented because Django used to accept such password
|
This class is implemented because Django used to accept such password
|
||||||
|
|
|
@ -12,7 +12,7 @@ from django.db import DEFAULT_DB_ALIAS, router
|
||||||
|
|
||||||
def _get_all_permissions(opts):
|
def _get_all_permissions(opts):
|
||||||
"""
|
"""
|
||||||
Returns (codename, name) for all permissions in the given opts.
|
Return (codename, name) for all permissions in the given opts.
|
||||||
"""
|
"""
|
||||||
builtin = _get_builtin_permissions(opts)
|
builtin = _get_builtin_permissions(opts)
|
||||||
custom = list(opts.permissions)
|
custom = list(opts.permissions)
|
||||||
|
@ -21,7 +21,7 @@ def _get_all_permissions(opts):
|
||||||
|
|
||||||
def _get_builtin_permissions(opts):
|
def _get_builtin_permissions(opts):
|
||||||
"""
|
"""
|
||||||
Returns (codename, name) for all autogenerated permissions.
|
Return (codename, name) for all autogenerated permissions.
|
||||||
By default, this is ('add', 'change', 'delete')
|
By default, this is ('add', 'change', 'delete')
|
||||||
"""
|
"""
|
||||||
perms = []
|
perms = []
|
||||||
|
|
|
@ -84,7 +84,7 @@ class RemoteUserMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
def clean_username(self, username, request):
|
def clean_username(self, username, request):
|
||||||
"""
|
"""
|
||||||
Allows the backend to clean the username, if the backend defines a
|
Allow the backend to clean the username, if the backend defines a
|
||||||
clean_username method.
|
clean_username method.
|
||||||
"""
|
"""
|
||||||
backend_str = request.session[auth.BACKEND_SESSION_KEY]
|
backend_str = request.session[auth.BACKEND_SESSION_KEY]
|
||||||
|
@ -97,7 +97,7 @@ class RemoteUserMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
def _remove_invalid_user(self, request):
|
def _remove_invalid_user(self, request):
|
||||||
"""
|
"""
|
||||||
Removes the current authenticated user in the request which is invalid
|
Remove the current authenticated user in the request which is invalid
|
||||||
but only if the user is authenticated via the RemoteUserBackend.
|
but only if the user is authenticated via the RemoteUserBackend.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -46,9 +46,7 @@ class AccessMixin:
|
||||||
|
|
||||||
|
|
||||||
class LoginRequiredMixin(AccessMixin):
|
class LoginRequiredMixin(AccessMixin):
|
||||||
"""
|
"""Verify that the current user is authenticated."""
|
||||||
CBV mixin which verifies that the current user is authenticated.
|
|
||||||
"""
|
|
||||||
def dispatch(self, request, *args, **kwargs):
|
def dispatch(self, request, *args, **kwargs):
|
||||||
if not request.user.is_authenticated:
|
if not request.user.is_authenticated:
|
||||||
return self.handle_no_permission()
|
return self.handle_no_permission()
|
||||||
|
@ -56,10 +54,7 @@ class LoginRequiredMixin(AccessMixin):
|
||||||
|
|
||||||
|
|
||||||
class PermissionRequiredMixin(AccessMixin):
|
class PermissionRequiredMixin(AccessMixin):
|
||||||
"""
|
"""Verify that the current user has all specified permissions."""
|
||||||
CBV mixin which verifies that the current user has all specified
|
|
||||||
permissions.
|
|
||||||
"""
|
|
||||||
permission_required = None
|
permission_required = None
|
||||||
|
|
||||||
def get_permission_required(self):
|
def get_permission_required(self):
|
||||||
|
@ -93,8 +88,8 @@ class PermissionRequiredMixin(AccessMixin):
|
||||||
|
|
||||||
class UserPassesTestMixin(AccessMixin):
|
class UserPassesTestMixin(AccessMixin):
|
||||||
"""
|
"""
|
||||||
CBV Mixin that allows you to define a test function which must return True
|
Deny a request with a permission error if the test_func() method returns
|
||||||
if the current user can access the view.
|
False.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def test_func(self):
|
def test_func(self):
|
||||||
|
|
|
@ -137,7 +137,7 @@ class UserManager(BaseUserManager):
|
||||||
|
|
||||||
def _create_user(self, username, email, password, **extra_fields):
|
def _create_user(self, username, email, password, **extra_fields):
|
||||||
"""
|
"""
|
||||||
Creates and saves a User with the given username, email and password.
|
Create and save a user with the given username, email, and password.
|
||||||
"""
|
"""
|
||||||
if not username:
|
if not username:
|
||||||
raise ValueError('The given username must be set')
|
raise ValueError('The given username must be set')
|
||||||
|
@ -206,8 +206,8 @@ def _user_has_module_perms(user, app_label):
|
||||||
|
|
||||||
class PermissionsMixin(models.Model):
|
class PermissionsMixin(models.Model):
|
||||||
"""
|
"""
|
||||||
A mixin class that adds the fields and methods necessary to support
|
Add the fields and methods necessary to support the Group and Permission
|
||||||
Django's Group and Permission model using the ModelBackend.
|
models using the ModelBackend.
|
||||||
"""
|
"""
|
||||||
is_superuser = models.BooleanField(
|
is_superuser = models.BooleanField(
|
||||||
_('superuser status'),
|
_('superuser status'),
|
||||||
|
@ -242,9 +242,9 @@ class PermissionsMixin(models.Model):
|
||||||
|
|
||||||
def get_group_permissions(self, obj=None):
|
def get_group_permissions(self, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns a list of permission strings that this user has through their
|
Return a list of permission strings that this user has through their
|
||||||
groups. This method queries all available auth backends. If an object
|
groups. Query all available auth backends. If an object is passed in,
|
||||||
is passed in, only permissions matching this object are returned.
|
return only permissions matching this object.
|
||||||
"""
|
"""
|
||||||
permissions = set()
|
permissions = set()
|
||||||
for backend in auth.get_backends():
|
for backend in auth.get_backends():
|
||||||
|
@ -257,13 +257,12 @@ class PermissionsMixin(models.Model):
|
||||||
|
|
||||||
def has_perm(self, perm, obj=None):
|
def has_perm(self, perm, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns True if the user has the specified permission. This method
|
Return True if the user has the specified permission. Query all
|
||||||
queries all available auth backends, but returns immediately if any
|
available auth backends, but return immediately if any backend returns
|
||||||
backend returns True. Thus, a user who has permission from a single
|
True. Thus, a user who has permission from a single auth backend is
|
||||||
auth backend is assumed to have permission in general. If an object is
|
assumed to have permission in general. If an object is provided, check
|
||||||
provided, permissions for this specific object are checked.
|
permissions for that object.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
# Active superusers have all permissions.
|
# Active superusers have all permissions.
|
||||||
if self.is_active and self.is_superuser:
|
if self.is_active and self.is_superuser:
|
||||||
return True
|
return True
|
||||||
|
@ -273,16 +272,15 @@ class PermissionsMixin(models.Model):
|
||||||
|
|
||||||
def has_perms(self, perm_list, obj=None):
|
def has_perms(self, perm_list, obj=None):
|
||||||
"""
|
"""
|
||||||
Returns True if the user has each of the specified permissions. If
|
Return True if the user has each of the specified permissions. If
|
||||||
object is passed, it checks if the user has all required perms for this
|
object is passed, check if the user has all required perms for it.
|
||||||
object.
|
|
||||||
"""
|
"""
|
||||||
return all(self.has_perm(perm, obj) for perm in perm_list)
|
return all(self.has_perm(perm, obj) for perm in perm_list)
|
||||||
|
|
||||||
def has_module_perms(self, app_label):
|
def has_module_perms(self, app_label):
|
||||||
"""
|
"""
|
||||||
Returns True if the user has any permissions in the given app label.
|
Return True if the user has any permissions in the given app label.
|
||||||
Uses pretty much the same logic as has_perm, above.
|
Use simlar logic as has_perm(), above.
|
||||||
"""
|
"""
|
||||||
# Active superusers have all permissions.
|
# Active superusers have all permissions.
|
||||||
if self.is_active and self.is_superuser:
|
if self.is_active and self.is_superuser:
|
||||||
|
@ -345,19 +343,17 @@ class AbstractUser(AbstractBaseUser, PermissionsMixin):
|
||||||
|
|
||||||
def get_full_name(self):
|
def get_full_name(self):
|
||||||
"""
|
"""
|
||||||
Returns the first_name plus the last_name, with a space in between.
|
Return the first_name plus the last_name, with a space in between.
|
||||||
"""
|
"""
|
||||||
full_name = '%s %s' % (self.first_name, self.last_name)
|
full_name = '%s %s' % (self.first_name, self.last_name)
|
||||||
return full_name.strip()
|
return full_name.strip()
|
||||||
|
|
||||||
def get_short_name(self):
|
def get_short_name(self):
|
||||||
"Returns the short name for the user."
|
"""Return the short name for the user."""
|
||||||
return self.first_name
|
return self.first_name
|
||||||
|
|
||||||
def email_user(self, subject, message, from_email=None, **kwargs):
|
def email_user(self, subject, message, from_email=None, **kwargs):
|
||||||
"""
|
"""Send an email to this user."""
|
||||||
Sends an email to this User.
|
|
||||||
"""
|
|
||||||
send_mail(subject, message, from_email, [self.email], **kwargs)
|
send_mail(subject, message, from_email, [self.email], **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ class PasswordResetTokenGenerator:
|
||||||
|
|
||||||
def make_token(self, user):
|
def make_token(self, user):
|
||||||
"""
|
"""
|
||||||
Returns a token that can be used once to do a password reset
|
Return a token that can be used once to do a password reset
|
||||||
for the given user.
|
for the given user.
|
||||||
"""
|
"""
|
||||||
return self._make_token_with_timestamp(user, self._num_days(self._today()))
|
return self._make_token_with_timestamp(user, self._num_days(self._today()))
|
||||||
|
|
|
@ -42,7 +42,7 @@ class SuccessURLAllowedHostsMixin:
|
||||||
|
|
||||||
class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
class LoginView(SuccessURLAllowedHostsMixin, FormView):
|
||||||
"""
|
"""
|
||||||
Displays the login form and handles the login action.
|
Display the login form and handle the login action.
|
||||||
"""
|
"""
|
||||||
form_class = AuthenticationForm
|
form_class = AuthenticationForm
|
||||||
authentication_form = None
|
authentication_form = None
|
||||||
|
@ -111,7 +111,7 @@ def login(request, *args, **kwargs):
|
||||||
|
|
||||||
class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):
|
class LogoutView(SuccessURLAllowedHostsMixin, TemplateView):
|
||||||
"""
|
"""
|
||||||
Logs out the user and displays 'You are logged out' message.
|
Log out the user and display the 'You are logged out' message.
|
||||||
"""
|
"""
|
||||||
next_page = None
|
next_page = None
|
||||||
redirect_field_name = REDIRECT_FIELD_NAME
|
redirect_field_name = REDIRECT_FIELD_NAME
|
||||||
|
@ -178,7 +178,7 @@ _sentinel = object()
|
||||||
|
|
||||||
def logout_then_login(request, login_url=None, extra_context=_sentinel):
|
def logout_then_login(request, login_url=None, extra_context=_sentinel):
|
||||||
"""
|
"""
|
||||||
Logs out the user if they are logged in. Then redirects to the log-in page.
|
Log out the user if they are logged in. Then redirect to the login page.
|
||||||
"""
|
"""
|
||||||
if extra_context is not _sentinel:
|
if extra_context is not _sentinel:
|
||||||
warnings.warn(
|
warnings.warn(
|
||||||
|
@ -192,10 +192,9 @@ def logout_then_login(request, login_url=None, extra_context=_sentinel):
|
||||||
return LogoutView.as_view(next_page=login_url)(request)
|
return LogoutView.as_view(next_page=login_url)(request)
|
||||||
|
|
||||||
|
|
||||||
def redirect_to_login(next, login_url=None,
|
def redirect_to_login(next, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
|
||||||
redirect_field_name=REDIRECT_FIELD_NAME):
|
|
||||||
"""
|
"""
|
||||||
Redirects the user to the login page, passing the given 'next' page
|
Redirect the user to the login page, passing the given 'next' page.
|
||||||
"""
|
"""
|
||||||
resolved_url = resolve_url(login_url or settings.LOGIN_URL)
|
resolved_url = resolve_url(login_url or settings.LOGIN_URL)
|
||||||
|
|
||||||
|
@ -286,8 +285,8 @@ def password_reset_confirm(request, uidb64=None, token=None,
|
||||||
post_reset_redirect=None,
|
post_reset_redirect=None,
|
||||||
extra_context=None):
|
extra_context=None):
|
||||||
"""
|
"""
|
||||||
View that checks the hash in a password reset link and presents a
|
Check the hash in a password reset link and present a form for entering a
|
||||||
form for entering a new password.
|
new password.
|
||||||
"""
|
"""
|
||||||
warnings.warn("The password_reset_confirm() view is superseded by the "
|
warnings.warn("The password_reset_confirm() view is superseded by the "
|
||||||
"class-based PasswordResetConfirmView().",
|
"class-based PasswordResetConfirmView().",
|
||||||
|
|
|
@ -49,7 +49,7 @@ def generic_inlineformset_factory(model, form=ModelForm,
|
||||||
validate_max=False, for_concrete_model=True,
|
validate_max=False, for_concrete_model=True,
|
||||||
min_num=None, validate_min=False):
|
min_num=None, validate_min=False):
|
||||||
"""
|
"""
|
||||||
Returns a ``GenericInlineFormSet`` for the given kwargs.
|
Return a ``GenericInlineFormSet`` for the given kwargs.
|
||||||
|
|
||||||
You must provide ``ct_field`` and ``fk_field`` if they are different from
|
You must provide ``ct_field`` and ``fk_field`` if they are different from
|
||||||
the defaults ``content_type`` and ``object_id`` respectively.
|
the defaults ``content_type`` and ``object_id`` respectively.
|
||||||
|
|
|
@ -103,7 +103,7 @@ def get_contenttypes_and_models(app_config, using, ContentType):
|
||||||
|
|
||||||
def create_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, apps=global_apps, **kwargs):
|
def create_contenttypes(app_config, verbosity=2, interactive=True, using=DEFAULT_DB_ALIAS, apps=global_apps, **kwargs):
|
||||||
"""
|
"""
|
||||||
Creates content types for models in the given app.
|
Create content types for models in the given app.
|
||||||
"""
|
"""
|
||||||
if not app_config.models_module:
|
if not app_config.models_module:
|
||||||
return
|
return
|
||||||
|
|
|
@ -34,7 +34,7 @@ class ContentTypeManager(models.Manager):
|
||||||
|
|
||||||
def get_for_model(self, model, for_concrete_model=True):
|
def get_for_model(self, model, for_concrete_model=True):
|
||||||
"""
|
"""
|
||||||
Returns the ContentType object for a given model, creating the
|
Return the ContentType object for a given model, creating the
|
||||||
ContentType if necessary. Lookups are cached so that subsequent lookups
|
ContentType if necessary. Lookups are cached so that subsequent lookups
|
||||||
for the same model don't hit the database.
|
for the same model don't hit the database.
|
||||||
"""
|
"""
|
||||||
|
@ -62,7 +62,7 @@ class ContentTypeManager(models.Manager):
|
||||||
|
|
||||||
def get_for_models(self, *models, for_concrete_models=True):
|
def get_for_models(self, *models, for_concrete_models=True):
|
||||||
"""
|
"""
|
||||||
Given *models, returns a dictionary mapping {model: content_type}.
|
Given *models, return a dictionary mapping {model: content_type}.
|
||||||
"""
|
"""
|
||||||
results = {}
|
results = {}
|
||||||
# Models that aren't already in the cache.
|
# Models that aren't already in the cache.
|
||||||
|
@ -105,7 +105,7 @@ class ContentTypeManager(models.Manager):
|
||||||
|
|
||||||
def get_for_id(self, id):
|
def get_for_id(self, id):
|
||||||
"""
|
"""
|
||||||
Lookup a ContentType by ID. Uses the same shared cache as get_for_model
|
Lookup a ContentType by ID. Use the same shared cache as get_for_model
|
||||||
(though ContentTypes are obviously not created on-the-fly by get_by_id).
|
(though ContentTypes are obviously not created on-the-fly by get_by_id).
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -154,7 +154,7 @@ class ContentType(models.Model):
|
||||||
return force_text(model._meta.verbose_name)
|
return force_text(model._meta.verbose_name)
|
||||||
|
|
||||||
def model_class(self):
|
def model_class(self):
|
||||||
"Returns the Python model class for this type of content."
|
"""Return the model class for this type of content."""
|
||||||
try:
|
try:
|
||||||
return apps.get_model(self.app_label, self.model)
|
return apps.get_model(self.app_label, self.model)
|
||||||
except LookupError:
|
except LookupError:
|
||||||
|
@ -162,7 +162,7 @@ class ContentType(models.Model):
|
||||||
|
|
||||||
def get_object_for_this_type(self, **kwargs):
|
def get_object_for_this_type(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns an object of this type for the keyword arguments given.
|
Return an object of this type for the keyword arguments given.
|
||||||
Basically, this is a proxy around this object_type's get_object() model
|
Basically, this is a proxy around this object_type's get_object() model
|
||||||
method. The ObjectNotExist exception, if thrown, will not be caught,
|
method. The ObjectNotExist exception, if thrown, will not be caught,
|
||||||
so code that calls this method should catch it.
|
so code that calls this method should catch it.
|
||||||
|
@ -171,7 +171,7 @@ class ContentType(models.Model):
|
||||||
|
|
||||||
def get_all_objects_for_this_type(self, **kwargs):
|
def get_all_objects_for_this_type(self, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns all objects of this type for the keyword arguments given.
|
Return all objects of this type for the keyword arguments given.
|
||||||
"""
|
"""
|
||||||
return self.model_class()._base_manager.using(self._state.db).filter(**kwargs)
|
return self.model_class()._base_manager.using(self._state.db).filter(**kwargs)
|
||||||
|
|
||||||
|
|
|
@ -45,18 +45,17 @@ class FlatpageNode(template.Node):
|
||||||
@register.tag
|
@register.tag
|
||||||
def get_flatpages(parser, token):
|
def get_flatpages(parser, token):
|
||||||
"""
|
"""
|
||||||
Retrieves all flatpage objects available for the current site and
|
Retrieve all flatpage objects available for the current site and
|
||||||
visible to the specific user (or visible to all users if no user is
|
visible to the specific user (or visible to all users if no user is
|
||||||
specified). Populates the template context with them in a variable
|
specified). Populate the template context with them in a variable
|
||||||
whose name is defined by the ``as`` clause.
|
whose name is defined by the ``as`` clause.
|
||||||
|
|
||||||
An optional ``for`` clause can be used to control the user whose
|
An optional ``for`` clause controls the user whose permissions are used in
|
||||||
permissions are to be used in determining which flatpages are visible.
|
determining which flatpages are visible.
|
||||||
|
|
||||||
An optional argument, ``starts_with``, can be applied to limit the
|
An optional argument, ``starts_with``, limits the returned flatpages to
|
||||||
returned flatpages to those beginning with a particular base URL.
|
those beginning with a particular base URL. This argument can be a variable
|
||||||
This argument can be passed as a variable or a string, as it resolves
|
or a string, as it resolves from the template context.
|
||||||
from the template context.
|
|
||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ class GeoModelAdmin(ModelAdmin):
|
||||||
|
|
||||||
def get_map_widget(self, db_field):
|
def get_map_widget(self, db_field):
|
||||||
"""
|
"""
|
||||||
Returns a subclass of the OpenLayersWidget (or whatever was specified
|
Return a subclass of the OpenLayersWidget (or whatever was specified
|
||||||
in the `widget` attribute) using the settings from the attributes set
|
in the `widget` attribute) using the settings from the attributes set
|
||||||
in this class.
|
in this class.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -13,7 +13,7 @@ logger = logging.getLogger('django.contrib.gis')
|
||||||
|
|
||||||
class OpenLayersWidget(Textarea):
|
class OpenLayersWidget(Textarea):
|
||||||
"""
|
"""
|
||||||
Renders an OpenLayers map using the WKT of the geometry.
|
Render an OpenLayers map using the WKT of the geometry.
|
||||||
"""
|
"""
|
||||||
def get_context(self, name, value, attrs=None):
|
def get_context(self, name, value, attrs=None):
|
||||||
# Update the template parameters with any attributes passed in.
|
# Update the template parameters with any attributes passed in.
|
||||||
|
@ -79,8 +79,7 @@ class OpenLayersWidget(Textarea):
|
||||||
return self.params
|
return self.params
|
||||||
|
|
||||||
def map_options(self):
|
def map_options(self):
|
||||||
"Builds the map options hash for the OpenLayers template."
|
"""Build the map options hash for the OpenLayers template."""
|
||||||
|
|
||||||
# JavaScript construction utilities for the Bounds and Projection.
|
# JavaScript construction utilities for the Bounds and Projection.
|
||||||
def ol_bounds(extent):
|
def ol_bounds(extent):
|
||||||
return 'new OpenLayers.Bounds(%s)' % extent
|
return 'new OpenLayers.Bounds(%s)' % extent
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class WKTAdapter:
|
class WKTAdapter:
|
||||||
"""
|
"""
|
||||||
This provides an adaptor for Geometries sent to the
|
An adaptor for Geometries sent to the MySQL and Oracle database backends.
|
||||||
MySQL and Oracle database backends.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, geom):
|
def __init__(self, geom):
|
||||||
self.wkt = geom.wkt
|
self.wkt = geom.wkt
|
||||||
|
|
|
@ -9,7 +9,7 @@ class SpatialRefSysMixin:
|
||||||
@property
|
@property
|
||||||
def srs(self):
|
def srs(self):
|
||||||
"""
|
"""
|
||||||
Returns a GDAL SpatialReference object.
|
Return a GDAL SpatialReference object.
|
||||||
"""
|
"""
|
||||||
# TODO: Is caching really necessary here? Is complexity worth it?
|
# TODO: Is caching really necessary here? Is complexity worth it?
|
||||||
if hasattr(self, '_srs'):
|
if hasattr(self, '_srs'):
|
||||||
|
@ -36,24 +36,24 @@ class SpatialRefSysMixin:
|
||||||
@property
|
@property
|
||||||
def ellipsoid(self):
|
def ellipsoid(self):
|
||||||
"""
|
"""
|
||||||
Returns a tuple of the ellipsoid parameters:
|
Return a tuple of the ellipsoid parameters:
|
||||||
(semimajor axis, semiminor axis, and inverse flattening).
|
(semimajor axis, semiminor axis, and inverse flattening).
|
||||||
"""
|
"""
|
||||||
return self.srs.ellipsoid
|
return self.srs.ellipsoid
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns the projection name."
|
"Return the projection name."
|
||||||
return self.srs.name
|
return self.srs.name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def spheroid(self):
|
def spheroid(self):
|
||||||
"Returns the spheroid name for this spatial reference."
|
"Return the spheroid name for this spatial reference."
|
||||||
return self.srs['spheroid']
|
return self.srs['spheroid']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def datum(self):
|
def datum(self):
|
||||||
"Returns the datum for this spatial reference."
|
"Return the datum for this spatial reference."
|
||||||
return self.srs['datum']
|
return self.srs['datum']
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -73,27 +73,27 @@ class SpatialRefSysMixin:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def linear_name(self):
|
def linear_name(self):
|
||||||
"Returns the linear units name."
|
"Return the linear units name."
|
||||||
return self.srs.linear_name
|
return self.srs.linear_name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def linear_units(self):
|
def linear_units(self):
|
||||||
"Returns the linear units."
|
"Return the linear units."
|
||||||
return self.srs.linear_units
|
return self.srs.linear_units
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def angular_name(self):
|
def angular_name(self):
|
||||||
"Returns the name of the angular units."
|
"Return the name of the angular units."
|
||||||
return self.srs.angular_name
|
return self.srs.angular_name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def angular_units(self):
|
def angular_units(self):
|
||||||
"Returns the angular units."
|
"Return the angular units."
|
||||||
return self.srs.angular_units
|
return self.srs.angular_units
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def units(self):
|
def units(self):
|
||||||
"Returns a tuple of the units and the name."
|
"Return a tuple of the units and the name."
|
||||||
if self.projected or self.local:
|
if self.projected or self.local:
|
||||||
return (self.linear_units, self.linear_name)
|
return (self.linear_units, self.linear_name)
|
||||||
elif self.geographic:
|
elif self.geographic:
|
||||||
|
@ -131,6 +131,6 @@ class SpatialRefSysMixin:
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""
|
"""
|
||||||
Returns the string representation, a 'pretty' OGC WKT.
|
Return the string representation, a 'pretty' OGC WKT.
|
||||||
"""
|
"""
|
||||||
return str(self.srs)
|
return str(self.srs)
|
||||||
|
|
|
@ -1,9 +1,4 @@
|
||||||
class BaseSpatialOperations:
|
class BaseSpatialOperations:
|
||||||
"""
|
|
||||||
This module holds the base `BaseSpatialBackend` object, which is
|
|
||||||
instantiated by each spatial database backend with the features
|
|
||||||
it has.
|
|
||||||
"""
|
|
||||||
truncate_params = {}
|
truncate_params = {}
|
||||||
|
|
||||||
# Quick booleans for the type of this spatial backend, and
|
# Quick booleans for the type of this spatial backend, and
|
||||||
|
@ -90,21 +85,21 @@ class BaseSpatialOperations:
|
||||||
# GeometryField operations
|
# GeometryField operations
|
||||||
def geo_db_type(self, f):
|
def geo_db_type(self, f):
|
||||||
"""
|
"""
|
||||||
Returns the database column type for the geometry field on
|
Return the database column type for the geometry field on
|
||||||
the spatial backend.
|
the spatial backend.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('subclasses of BaseSpatialOperations must provide a geo_db_type() method')
|
raise NotImplementedError('subclasses of BaseSpatialOperations must provide a geo_db_type() method')
|
||||||
|
|
||||||
def get_distance(self, f, value, lookup_type):
|
def get_distance(self, f, value, lookup_type):
|
||||||
"""
|
"""
|
||||||
Returns the distance parameters for the given geometry field,
|
Return the distance parameters for the given geometry field,
|
||||||
lookup value, and lookup type.
|
lookup value, and lookup type.
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError('Distance operations not available on this spatial backend.')
|
raise NotImplementedError('Distance operations not available on this spatial backend.')
|
||||||
|
|
||||||
def get_geom_placeholder(self, f, value, compiler):
|
def get_geom_placeholder(self, f, value, compiler):
|
||||||
"""
|
"""
|
||||||
Returns the placeholder for the given geometry field with the given
|
Return the placeholder for the given geometry field with the given
|
||||||
value. Depending on the spatial backend, the placeholder may contain a
|
value. Depending on the spatial backend, the placeholder may contain a
|
||||||
stored procedure call to the transformation function of the spatial
|
stored procedure call to the transformation function of the spatial
|
||||||
backend.
|
backend.
|
||||||
|
|
|
@ -24,7 +24,7 @@ class OracleSpatialAdapter(WKTAdapter):
|
||||||
self.srid = geom.srid
|
self.srid = geom.srid
|
||||||
|
|
||||||
def _fix_polygon(self, poly):
|
def _fix_polygon(self, poly):
|
||||||
# Fix single polygon orientation as described in __init__()
|
"""Fix single polygon orientation as described in __init__()."""
|
||||||
if self._isClockwise(poly.exterior_ring):
|
if self._isClockwise(poly.exterior_ring):
|
||||||
poly.exterior_ring = list(reversed(poly.exterior_ring))
|
poly.exterior_ring = list(reversed(poly.exterior_ring))
|
||||||
|
|
||||||
|
@ -35,15 +35,19 @@ class OracleSpatialAdapter(WKTAdapter):
|
||||||
return poly
|
return poly
|
||||||
|
|
||||||
def _fix_geometry_collection(self, coll):
|
def _fix_geometry_collection(self, coll):
|
||||||
# Fix polygon orientations in geometry collections as described in
|
"""
|
||||||
# __init__()
|
Fix polygon orientations in geometry collections as described in
|
||||||
|
__init__().
|
||||||
|
"""
|
||||||
for i, geom in enumerate(coll):
|
for i, geom in enumerate(coll):
|
||||||
if isinstance(geom, Polygon):
|
if isinstance(geom, Polygon):
|
||||||
coll[i] = self._fix_polygon(geom)
|
coll[i] = self._fix_polygon(geom)
|
||||||
|
|
||||||
def _isClockwise(self, coords):
|
def _isClockwise(self, coords):
|
||||||
# A modified shoelace algorithm to determine polygon orientation.
|
"""
|
||||||
# See https://en.wikipedia.org/wiki/Shoelace_formula
|
A modified shoelace algorithm to determine polygon orientation.
|
||||||
|
See https://en.wikipedia.org/wiki/Shoelace_formula.
|
||||||
|
"""
|
||||||
n = len(coords)
|
n = len(coords)
|
||||||
area = 0.0
|
area = 0.0
|
||||||
for i in range(n):
|
for i in range(n):
|
||||||
|
|
|
@ -26,7 +26,7 @@ class OracleGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def table_name_col(cls):
|
def table_name_col(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature table
|
Return the name of the metadata column used to store the feature table
|
||||||
name.
|
name.
|
||||||
"""
|
"""
|
||||||
return 'table_name'
|
return 'table_name'
|
||||||
|
@ -34,7 +34,7 @@ class OracleGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def geom_col_name(cls):
|
def geom_col_name(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature
|
Return the name of the metadata column used to store the feature
|
||||||
geometry column.
|
geometry column.
|
||||||
"""
|
"""
|
||||||
return 'column_name'
|
return 'column_name'
|
||||||
|
|
|
@ -185,7 +185,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def geo_db_type(self, f):
|
def geo_db_type(self, f):
|
||||||
"""
|
"""
|
||||||
Returns the geometry database type for Oracle. Unlike other spatial
|
Return the geometry database type for Oracle. Unlike other spatial
|
||||||
backends, no stored procedure is necessary and it's the same for all
|
backends, no stored procedure is necessary and it's the same for all
|
||||||
geometry types.
|
geometry types.
|
||||||
"""
|
"""
|
||||||
|
@ -193,7 +193,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def get_distance(self, f, value, lookup_type, **kwargs):
|
def get_distance(self, f, value, lookup_type, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns the distance parameters given the value and the lookup type.
|
Return the distance parameters given the value and the lookup type.
|
||||||
On Oracle, geometry columns with a geodetic coordinate system behave
|
On Oracle, geometry columns with a geodetic coordinate system behave
|
||||||
implicitly like a geography column, and thus meters will be used as
|
implicitly like a geography column, and thus meters will be used as
|
||||||
the distance parameter on them.
|
the distance parameter on them.
|
||||||
|
@ -218,7 +218,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def get_geom_placeholder(self, f, value, compiler):
|
def get_geom_placeholder(self, f, value, compiler):
|
||||||
"""
|
"""
|
||||||
Provides a proper substitution value for Geometries that are not in the
|
Provide a proper substitution value for Geometries that are not in the
|
||||||
SRID of the field. Specifically, this routine will substitute in the
|
SRID of the field. Specifically, this routine will substitute in the
|
||||||
SDO_CS.TRANSFORM() function call.
|
SDO_CS.TRANSFORM() function call.
|
||||||
"""
|
"""
|
||||||
|
@ -245,7 +245,7 @@ class OracleOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def spatial_aggregate_name(self, agg_name):
|
def spatial_aggregate_name(self, agg_name):
|
||||||
"""
|
"""
|
||||||
Returns the spatial aggregate SQL name.
|
Return the spatial aggregate SQL name.
|
||||||
"""
|
"""
|
||||||
agg_name = 'unionagg' if agg_name.lower() == 'union' else agg_name.lower()
|
agg_name = 'unionagg' if agg_name.lower() == 'union' else agg_name.lower()
|
||||||
return getattr(self, agg_name)
|
return getattr(self, agg_name)
|
||||||
|
|
|
@ -27,7 +27,7 @@ class PostGISAdapter:
|
||||||
self.geography = geography
|
self.geography = geography
|
||||||
|
|
||||||
def __conform__(self, proto):
|
def __conform__(self, proto):
|
||||||
# Does the given protocol conform to what Psycopg2 expects?
|
"""Does the given protocol conform to what Psycopg2 expects?"""
|
||||||
if proto == ISQLQuote:
|
if proto == ISQLQuote:
|
||||||
return self
|
return self
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -41,7 +41,7 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
|
|
||||||
def get_postgis_types(self):
|
def get_postgis_types(self):
|
||||||
"""
|
"""
|
||||||
Returns a dictionary with keys that are the PostgreSQL object
|
Return a dictionary with keys that are the PostgreSQL object
|
||||||
identification integers for the PostGIS geometry and/or
|
identification integers for the PostGIS geometry and/or
|
||||||
geography types (if supported).
|
geography types (if supported).
|
||||||
"""
|
"""
|
||||||
|
@ -86,7 +86,7 @@ class PostGISIntrospection(DatabaseIntrospection):
|
||||||
The geometry type OID used by PostGIS does not indicate the particular
|
The geometry type OID used by PostGIS does not indicate the particular
|
||||||
type of field that a geometry column is (e.g., whether it's a
|
type of field that a geometry column is (e.g., whether it's a
|
||||||
PointField or a PolygonField). Thus, this routine queries the PostGIS
|
PointField or a PolygonField). Thus, this routine queries the PostGIS
|
||||||
metadata tables to determine the geometry type,
|
metadata tables to determine the geometry type.
|
||||||
"""
|
"""
|
||||||
cursor = self.connection.cursor()
|
cursor = self.connection.cursor()
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -26,7 +26,7 @@ class PostGISGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def table_name_col(cls):
|
def table_name_col(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature table
|
Return the name of the metadata column used to store the feature table
|
||||||
name.
|
name.
|
||||||
"""
|
"""
|
||||||
return 'f_table_name'
|
return 'f_table_name'
|
||||||
|
@ -34,7 +34,7 @@ class PostGISGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def geom_col_name(cls):
|
def geom_col_name(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature
|
Return the name of the metadata column used to store the feature
|
||||||
geometry column.
|
geometry column.
|
||||||
"""
|
"""
|
||||||
return 'f_geometry_column'
|
return 'f_geometry_column'
|
||||||
|
|
|
@ -240,7 +240,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def convert_extent(self, box, srid):
|
def convert_extent(self, box, srid):
|
||||||
"""
|
"""
|
||||||
Returns a 4-tuple extent for the `Extent` aggregate by converting
|
Return a 4-tuple extent for the `Extent` aggregate by converting
|
||||||
the bounding box text returned by PostGIS (`box` argument), for
|
the bounding box text returned by PostGIS (`box` argument), for
|
||||||
example: "BOX(-90.0 30.0, -85.0 40.0)".
|
example: "BOX(-90.0 30.0, -85.0 40.0)".
|
||||||
"""
|
"""
|
||||||
|
@ -253,7 +253,7 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def convert_extent3d(self, box3d, srid):
|
def convert_extent3d(self, box3d, srid):
|
||||||
"""
|
"""
|
||||||
Returns a 6-tuple extent for the `Extent3D` aggregate by converting
|
Return a 6-tuple extent for the `Extent3D` aggregate by converting
|
||||||
the 3d bounding-box text returned by PostGIS (`box3d` argument), for
|
the 3d bounding-box text returned by PostGIS (`box3d` argument), for
|
||||||
example: "BOX3D(-90.0 30.0 1, -85.0 40.0 2)".
|
example: "BOX3D(-90.0 30.0 1, -85.0 40.0 2)".
|
||||||
"""
|
"""
|
||||||
|
@ -369,28 +369,28 @@ class PostGISOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
return cursor.fetchone()[0]
|
return cursor.fetchone()[0]
|
||||||
|
|
||||||
def postgis_geos_version(self):
|
def postgis_geos_version(self):
|
||||||
"Returns the version of the GEOS library used with PostGIS."
|
"Return the version of the GEOS library used with PostGIS."
|
||||||
return self._get_postgis_func('postgis_geos_version')
|
return self._get_postgis_func('postgis_geos_version')
|
||||||
|
|
||||||
def postgis_lib_version(self):
|
def postgis_lib_version(self):
|
||||||
"Returns the version number of the PostGIS library used with PostgreSQL."
|
"Return the version number of the PostGIS library used with PostgreSQL."
|
||||||
return self._get_postgis_func('postgis_lib_version')
|
return self._get_postgis_func('postgis_lib_version')
|
||||||
|
|
||||||
def postgis_proj_version(self):
|
def postgis_proj_version(self):
|
||||||
"Returns the version of the PROJ.4 library used with PostGIS."
|
"Return the version of the PROJ.4 library used with PostGIS."
|
||||||
return self._get_postgis_func('postgis_proj_version')
|
return self._get_postgis_func('postgis_proj_version')
|
||||||
|
|
||||||
def postgis_version(self):
|
def postgis_version(self):
|
||||||
"Returns PostGIS version number and compile-time options."
|
"Return PostGIS version number and compile-time options."
|
||||||
return self._get_postgis_func('postgis_version')
|
return self._get_postgis_func('postgis_version')
|
||||||
|
|
||||||
def postgis_full_version(self):
|
def postgis_full_version(self):
|
||||||
"Returns PostGIS version number and compile-time options."
|
"Return PostGIS version number and compile-time options."
|
||||||
return self._get_postgis_func('postgis_full_version')
|
return self._get_postgis_func('postgis_full_version')
|
||||||
|
|
||||||
def postgis_version_tuple(self):
|
def postgis_version_tuple(self):
|
||||||
"""
|
"""
|
||||||
Returns the PostGIS version as a tuple (version string, major,
|
Return the PostGIS version as a tuple (version string, major,
|
||||||
minor, subminor).
|
minor, subminor).
|
||||||
"""
|
"""
|
||||||
# Getting the PostGIS version
|
# Getting the PostGIS version
|
||||||
|
|
|
@ -3,7 +3,7 @@ from django.db.backends.sqlite3.base import Database
|
||||||
|
|
||||||
|
|
||||||
class SpatiaLiteAdapter(WKTAdapter):
|
class SpatiaLiteAdapter(WKTAdapter):
|
||||||
"SQLite adaptor for geometry objects."
|
"SQLite adapter for geometry objects."
|
||||||
def __conform__(self, protocol):
|
def __conform__(self, protocol):
|
||||||
if protocol is Database.PrepareProtocol:
|
if protocol is Database.PrepareProtocol:
|
||||||
return str(self)
|
return str(self)
|
||||||
|
|
|
@ -24,7 +24,7 @@ class SpatialiteGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def table_name_col(cls):
|
def table_name_col(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature table
|
Return the name of the metadata column used to store the feature table
|
||||||
name.
|
name.
|
||||||
"""
|
"""
|
||||||
return 'f_table_name'
|
return 'f_table_name'
|
||||||
|
@ -32,7 +32,7 @@ class SpatialiteGeometryColumns(models.Model):
|
||||||
@classmethod
|
@classmethod
|
||||||
def geom_col_name(cls):
|
def geom_col_name(cls):
|
||||||
"""
|
"""
|
||||||
Returns the name of the metadata column used to store the feature
|
Return the name of the metadata column used to store the feature
|
||||||
geometry column.
|
geometry column.
|
||||||
"""
|
"""
|
||||||
return 'f_geometry_column'
|
return 'f_geometry_column'
|
||||||
|
|
|
@ -145,14 +145,14 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def geo_db_type(self, f):
|
def geo_db_type(self, f):
|
||||||
"""
|
"""
|
||||||
Returns None because geometry columns are added via the
|
Return None because geometry columns are added via the
|
||||||
`AddGeometryColumn` stored procedure on SpatiaLite.
|
`AddGeometryColumn` stored procedure on SpatiaLite.
|
||||||
"""
|
"""
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def get_distance(self, f, value, lookup_type, **kwargs):
|
def get_distance(self, f, value, lookup_type, **kwargs):
|
||||||
"""
|
"""
|
||||||
Returns the distance parameters for the given geometry field,
|
Return the distance parameters for the given geometry field,
|
||||||
lookup value, and lookup type.
|
lookup value, and lookup type.
|
||||||
"""
|
"""
|
||||||
if not value:
|
if not value:
|
||||||
|
@ -174,7 +174,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def get_geom_placeholder(self, f, value, compiler):
|
def get_geom_placeholder(self, f, value, compiler):
|
||||||
"""
|
"""
|
||||||
Provides a proper substitution value for Geometries that are not in the
|
Provide a proper substitution value for Geometries that are not in the
|
||||||
SRID of the field. Specifically, this routine will substitute in the
|
SRID of the field. Specifically, this routine will substitute in the
|
||||||
Transform() and GeomFromText() function call(s).
|
Transform() and GeomFromText() function call(s).
|
||||||
"""
|
"""
|
||||||
|
@ -211,11 +211,11 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
return row[0]
|
return row[0]
|
||||||
|
|
||||||
def geos_version(self):
|
def geos_version(self):
|
||||||
"Returns the version of GEOS used by SpatiaLite as a string."
|
"Return the version of GEOS used by SpatiaLite as a string."
|
||||||
return self._get_spatialite_func('geos_version()')
|
return self._get_spatialite_func('geos_version()')
|
||||||
|
|
||||||
def proj4_version(self):
|
def proj4_version(self):
|
||||||
"Returns the version of the PROJ.4 library used by SpatiaLite."
|
"Return the version of the PROJ.4 library used by SpatiaLite."
|
||||||
return self._get_spatialite_func('proj4_version()')
|
return self._get_spatialite_func('proj4_version()')
|
||||||
|
|
||||||
def lwgeom_version(self):
|
def lwgeom_version(self):
|
||||||
|
@ -223,12 +223,12 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
return self._get_spatialite_func('lwgeom_version()')
|
return self._get_spatialite_func('lwgeom_version()')
|
||||||
|
|
||||||
def spatialite_version(self):
|
def spatialite_version(self):
|
||||||
"Returns the SpatiaLite library version as a string."
|
"Return the SpatiaLite library version as a string."
|
||||||
return self._get_spatialite_func('spatialite_version()')
|
return self._get_spatialite_func('spatialite_version()')
|
||||||
|
|
||||||
def spatialite_version_tuple(self):
|
def spatialite_version_tuple(self):
|
||||||
"""
|
"""
|
||||||
Returns the SpatiaLite version as a tuple (version string, major,
|
Return the SpatiaLite version as a tuple (version string, major,
|
||||||
minor, subminor).
|
minor, subminor).
|
||||||
"""
|
"""
|
||||||
version = self.spatialite_version()
|
version = self.spatialite_version()
|
||||||
|
@ -245,7 +245,7 @@ class SpatiaLiteOperations(BaseSpatialOperations, DatabaseOperations):
|
||||||
|
|
||||||
def spatial_aggregate_name(self, agg_name):
|
def spatial_aggregate_name(self, agg_name):
|
||||||
"""
|
"""
|
||||||
Returns the spatial aggregate SQL template and function for the
|
Return the spatial aggregate SQL template and function for the
|
||||||
given Aggregate instance.
|
given Aggregate instance.
|
||||||
"""
|
"""
|
||||||
agg_name = 'unionagg' if agg_name.lower() == 'union' else agg_name.lower()
|
agg_name = 'unionagg' if agg_name.lower() == 'union' else agg_name.lower()
|
||||||
|
|
|
@ -20,7 +20,7 @@ _srid_cache = defaultdict(dict)
|
||||||
|
|
||||||
def get_srid_info(srid, connection):
|
def get_srid_info(srid, connection):
|
||||||
"""
|
"""
|
||||||
Returns the units, unit name, and spheroid WKT associated with the
|
Return the units, unit name, and spheroid WKT associated with the
|
||||||
given SRID from the `spatial_ref_sys` (or equivalent) spatial database
|
given SRID from the `spatial_ref_sys` (or equivalent) spatial database
|
||||||
table for the given database connection. These results are cached.
|
table for the given database connection. These results are cached.
|
||||||
"""
|
"""
|
||||||
|
@ -51,10 +51,10 @@ def get_srid_info(srid, connection):
|
||||||
class GeoSelectFormatMixin:
|
class GeoSelectFormatMixin:
|
||||||
def select_format(self, compiler, sql, params):
|
def select_format(self, compiler, sql, params):
|
||||||
"""
|
"""
|
||||||
Returns the selection format string, depending on the requirements
|
Return the selection format string, depending on the requirements
|
||||||
of the spatial backend. For example, Oracle and MySQL require custom
|
of the spatial backend. For example, Oracle and MySQL require custom
|
||||||
selection formats in order to retrieve geometries in OGC WKT. For all
|
selection formats in order to retrieve geometries in OGC WKT. For all
|
||||||
other fields a simple '%s' format string is returned.
|
other fields, return a simple '%s' format string.
|
||||||
"""
|
"""
|
||||||
connection = compiler.connection
|
connection = compiler.connection
|
||||||
srid = compiler.query.get_context('transformed_srid')
|
srid = compiler.query.get_context('transformed_srid')
|
||||||
|
@ -147,7 +147,7 @@ class BaseSpatialField(Field):
|
||||||
|
|
||||||
def geodetic(self, connection):
|
def geodetic(self, connection):
|
||||||
"""
|
"""
|
||||||
Returns true if this field's SRID corresponds with a coordinate
|
Return true if this field's SRID corresponds with a coordinate
|
||||||
system that uses non-projected units (e.g., latitude/longitude).
|
system that uses non-projected units (e.g., latitude/longitude).
|
||||||
"""
|
"""
|
||||||
units_name = self.units_name(connection)
|
units_name = self.units_name(connection)
|
||||||
|
@ -155,7 +155,7 @@ class BaseSpatialField(Field):
|
||||||
|
|
||||||
def get_placeholder(self, value, compiler, connection):
|
def get_placeholder(self, value, compiler, connection):
|
||||||
"""
|
"""
|
||||||
Returns the placeholder for the spatial column for the
|
Return the placeholder for the spatial column for the
|
||||||
given value.
|
given value.
|
||||||
"""
|
"""
|
||||||
return connection.ops.get_geom_placeholder(self, value, compiler)
|
return connection.ops.get_geom_placeholder(self, value, compiler)
|
||||||
|
@ -203,9 +203,8 @@ class BaseSpatialField(Field):
|
||||||
"""
|
"""
|
||||||
Spatial lookup values are either a parameter that is (or may be
|
Spatial lookup values are either a parameter that is (or may be
|
||||||
converted to) a geometry or raster, or a sequence of lookup values
|
converted to) a geometry or raster, or a sequence of lookup values
|
||||||
that begins with a geometry or raster. This routine sets up the
|
that begins with a geometry or raster. Set up the geometry or raster
|
||||||
geometry or raster value properly and preserves any other lookup
|
value properly and preserves any other lookup parameters.
|
||||||
parameters.
|
|
||||||
"""
|
"""
|
||||||
value = super().get_prep_value(value)
|
value = super().get_prep_value(value)
|
||||||
|
|
||||||
|
@ -307,7 +306,7 @@ class GeometryField(GeoSelectFormatMixin, BaseSpatialField):
|
||||||
# ### Routines specific to GeometryField ###
|
# ### Routines specific to GeometryField ###
|
||||||
def get_distance(self, value, lookup_type, connection):
|
def get_distance(self, value, lookup_type, connection):
|
||||||
"""
|
"""
|
||||||
Returns a distance number in units of the field. For example, if
|
Return a distance number in units of the field. For example, if
|
||||||
`D(km=1)` was passed in and the units of the field were in meters,
|
`D(km=1)` was passed in and the units of the field were in meters,
|
||||||
then 1000 would be returned.
|
then 1000 would be returned.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -28,13 +28,13 @@ class GISLookup(Lookup):
|
||||||
@classmethod
|
@classmethod
|
||||||
def _check_geo_field(cls, opts, lookup):
|
def _check_geo_field(cls, opts, lookup):
|
||||||
"""
|
"""
|
||||||
Utility for checking the given lookup with the given model options.
|
Check the given lookup with the given model options.
|
||||||
The lookup is a string either specifying the geographic field, e.g.
|
The lookup is a string either specifying the geographic field, e.g.
|
||||||
'point, 'the_geom', or a related lookup on a geographic field like
|
'point, 'the_geom', or a related lookup on a geographic field like
|
||||||
'address__point'.
|
'address__point'.
|
||||||
|
|
||||||
If a BaseSpatialField exists according to the given lookup on the model
|
Return a BaseSpatialField if one exists according to the given lookup
|
||||||
options, it will be returned. Otherwise return None.
|
on the model options, otherwise return None.
|
||||||
"""
|
"""
|
||||||
from django.contrib.gis.db.models.fields import BaseSpatialField
|
from django.contrib.gis.db.models.fields import BaseSpatialField
|
||||||
# This takes into account the situation where the lookup is a
|
# This takes into account the situation where the lookup is a
|
||||||
|
|
|
@ -11,7 +11,7 @@ from django.db.models.query_utils import DeferredAttribute
|
||||||
class SpatialProxy(DeferredAttribute):
|
class SpatialProxy(DeferredAttribute):
|
||||||
def __init__(self, klass, field):
|
def __init__(self, klass, field):
|
||||||
"""
|
"""
|
||||||
Proxy initializes on the given Geometry or Raster class (not an instance)
|
Initialize on the given Geometry or Raster class (not an instance)
|
||||||
and the corresponding field.
|
and the corresponding field.
|
||||||
"""
|
"""
|
||||||
self._field = field
|
self._field = field
|
||||||
|
@ -20,10 +20,10 @@ class SpatialProxy(DeferredAttribute):
|
||||||
|
|
||||||
def __get__(self, instance, cls=None):
|
def __get__(self, instance, cls=None):
|
||||||
"""
|
"""
|
||||||
This accessor retrieves the geometry or raster, initializing it using
|
Retrieve the geometry or raster, initializing it using the
|
||||||
the corresponding class specified during initialization and the value
|
corresponding class specified during initialization and the value of
|
||||||
of the field. Currently, GEOS or OGR geometries as well as GDALRasters
|
the field. Currently, GEOS or OGR geometries as well as GDALRasters are
|
||||||
are supported.
|
supported.
|
||||||
"""
|
"""
|
||||||
if instance is None:
|
if instance is None:
|
||||||
# Accessed on a class, not an instance
|
# Accessed on a class, not an instance
|
||||||
|
@ -48,11 +48,11 @@ class SpatialProxy(DeferredAttribute):
|
||||||
|
|
||||||
def __set__(self, instance, value):
|
def __set__(self, instance, value):
|
||||||
"""
|
"""
|
||||||
This accessor sets the proxied geometry or raster with the
|
Retrieve the proxied geometry or raster with the corresponding class
|
||||||
corresponding class specified during initialization.
|
specified during initialization.
|
||||||
|
|
||||||
To set geometries, values of None, HEXEWKB, or WKT may be used.
|
To set geometries, use values of None, HEXEWKB, or WKT.
|
||||||
To set rasters, JSON or dict values may be used.
|
To set rasters, use JSON or dict values.
|
||||||
"""
|
"""
|
||||||
# The geographic type of the field.
|
# The geographic type of the field.
|
||||||
gtype = self._field.geom_type
|
gtype = self._field.geom_type
|
||||||
|
|
|
@ -30,9 +30,7 @@ class GeoFeedMixin:
|
||||||
handler.addQuickElement('georss:point', self.georss_coords((coords,)))
|
handler.addQuickElement('georss:point', self.georss_coords((coords,)))
|
||||||
|
|
||||||
def add_georss_element(self, handler, item, w3c_geo=False):
|
def add_georss_element(self, handler, item, w3c_geo=False):
|
||||||
"""
|
"""Add a GeoRSS XML element using the given item and handler."""
|
||||||
This routine adds a GeoRSS XML element using the given item and handler.
|
|
||||||
"""
|
|
||||||
# Getting the Geometry object.
|
# Getting the Geometry object.
|
||||||
geom = item.get('geometry')
|
geom = item.get('geometry')
|
||||||
if geom is not None:
|
if geom is not None:
|
||||||
|
|
|
@ -30,9 +30,7 @@ class GeometryField(forms.Field):
|
||||||
self.widget.attrs['geom_type'] = self.geom_type
|
self.widget.attrs['geom_type'] = self.geom_type
|
||||||
|
|
||||||
def to_python(self, value):
|
def to_python(self, value):
|
||||||
"""
|
"""Transform the value to a Geometry object."""
|
||||||
Transforms the value to a Geometry object.
|
|
||||||
"""
|
|
||||||
if value in self.empty_values:
|
if value in self.empty_values:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
@ -53,9 +51,9 @@ class GeometryField(forms.Field):
|
||||||
|
|
||||||
def clean(self, value):
|
def clean(self, value):
|
||||||
"""
|
"""
|
||||||
Validates that the input value can be converted to a Geometry
|
Validate that the input value can be converted to a Geometry object
|
||||||
object (which is returned). A ValidationError is raised if
|
and return it. Raise a ValidationError if the value cannot be
|
||||||
the value cannot be instantiated as a Geometry.
|
instantiated as a Geometry.
|
||||||
"""
|
"""
|
||||||
geom = super().clean(value)
|
geom = super().clean(value)
|
||||||
if geom is None:
|
if geom is None:
|
||||||
|
|
|
@ -12,7 +12,7 @@ logger = logging.getLogger('django.contrib.gis')
|
||||||
class BaseGeometryWidget(Widget):
|
class BaseGeometryWidget(Widget):
|
||||||
"""
|
"""
|
||||||
The base class for rich geometry widgets.
|
The base class for rich geometry widgets.
|
||||||
Renders a map using the WKT of the geometry.
|
Render a map using the WKT of the geometry.
|
||||||
"""
|
"""
|
||||||
geom_type = 'GEOMETRY'
|
geom_type = 'GEOMETRY'
|
||||||
map_srid = 4326
|
map_srid = 4326
|
||||||
|
|
|
@ -104,20 +104,20 @@ class DataSource(GDALBase):
|
||||||
return Layer(layer, self)
|
return Layer(layer, self)
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of layers within the data source."
|
"Return the number of layers within the data source."
|
||||||
return self.layer_count
|
return self.layer_count
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns OGR GetName and Driver for the Data Source."
|
"Return OGR GetName and Driver for the Data Source."
|
||||||
return '%s (%s)' % (self.name, self.driver)
|
return '%s (%s)' % (self.name, self.driver)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def layer_count(self):
|
def layer_count(self):
|
||||||
"Returns the number of layers in the data source."
|
"Return the number of layers in the data source."
|
||||||
return capi.get_layer_count(self._ptr)
|
return capi.get_layer_count(self._ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns the name of the data source."
|
"Return the name of the data source."
|
||||||
name = capi.get_ds_name(self._ptr)
|
name = capi.get_ds_name(self._ptr)
|
||||||
return force_text(name, self.encoding, strings_only=True)
|
return force_text(name, self.encoding, strings_only=True)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.utils.encoding import force_bytes, force_text
|
||||||
|
|
||||||
class Driver(GDALBase):
|
class Driver(GDALBase):
|
||||||
"""
|
"""
|
||||||
Wraps a GDAL/OGR Data Source Driver.
|
Wrap a GDAL/OGR Data Source Driver.
|
||||||
For more information, see the C API source code:
|
For more information, see the C API source code:
|
||||||
http://www.gdal.org/gdal_8h.html - http://www.gdal.org/ogr__api_8h.html
|
http://www.gdal.org/gdal_8h.html - http://www.gdal.org/ogr__api_8h.html
|
||||||
"""
|
"""
|
||||||
|
@ -33,7 +33,7 @@ class Driver(GDALBase):
|
||||||
|
|
||||||
def __init__(self, dr_input):
|
def __init__(self, dr_input):
|
||||||
"""
|
"""
|
||||||
Initializes an GDAL/OGR driver on either a string or integer input.
|
Initialize an GDAL/OGR driver on either a string or integer input.
|
||||||
"""
|
"""
|
||||||
if isinstance(dr_input, str):
|
if isinstance(dr_input, str):
|
||||||
# If a string name of the driver was passed in
|
# If a string name of the driver was passed in
|
||||||
|
@ -73,7 +73,7 @@ class Driver(GDALBase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def ensure_registered(cls):
|
def ensure_registered(cls):
|
||||||
"""
|
"""
|
||||||
Attempts to register all the data source drivers.
|
Attempt to register all the data source drivers.
|
||||||
"""
|
"""
|
||||||
# Only register all if the driver counts are 0 (or else all drivers
|
# Only register all if the driver counts are 0 (or else all drivers
|
||||||
# will be registered over and over again)
|
# will be registered over and over again)
|
||||||
|
@ -85,13 +85,13 @@ class Driver(GDALBase):
|
||||||
@classmethod
|
@classmethod
|
||||||
def driver_count(cls):
|
def driver_count(cls):
|
||||||
"""
|
"""
|
||||||
Returns the number of GDAL/OGR data source drivers registered.
|
Return the number of GDAL/OGR data source drivers registered.
|
||||||
"""
|
"""
|
||||||
return vcapi.get_driver_count() + rcapi.get_driver_count()
|
return vcapi.get_driver_count() + rcapi.get_driver_count()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
Returns description/name string for this driver.
|
Return description/name string for this driver.
|
||||||
"""
|
"""
|
||||||
return force_text(rcapi.get_driver_description(self.ptr))
|
return force_text(rcapi.get_driver_description(self.ptr))
|
||||||
|
|
|
@ -19,7 +19,7 @@ from django.contrib.gis.gdal.error import GDALException
|
||||||
# See the 'ogr_core.h' source file for more information:
|
# See the 'ogr_core.h' source file for more information:
|
||||||
# http://www.gdal.org/ogr__core_8h_source.html
|
# http://www.gdal.org/ogr__core_8h_source.html
|
||||||
class OGREnvelope(Structure):
|
class OGREnvelope(Structure):
|
||||||
"Represents the OGREnvelope C Structure."
|
"Represent the OGREnvelope C Structure."
|
||||||
_fields_ = [("MinX", c_double),
|
_fields_ = [("MinX", c_double),
|
||||||
("MaxX", c_double),
|
("MaxX", c_double),
|
||||||
("MinY", c_double),
|
("MinY", c_double),
|
||||||
|
@ -67,7 +67,7 @@ class Envelope:
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
Returns True if the envelopes are equivalent; can compare against
|
Return True if the envelopes are equivalent; can compare against
|
||||||
other Envelopes and 4-tuples.
|
other Envelopes and 4-tuples.
|
||||||
"""
|
"""
|
||||||
if isinstance(other, Envelope):
|
if isinstance(other, Envelope):
|
||||||
|
@ -80,11 +80,11 @@ class Envelope:
|
||||||
raise GDALException('Equivalence testing only works with other Envelopes.')
|
raise GDALException('Equivalence testing only works with other Envelopes.')
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns a string representation of the tuple."
|
"Return a string representation of the tuple."
|
||||||
return str(self.tuple)
|
return str(self.tuple)
|
||||||
|
|
||||||
def _from_sequence(self, seq):
|
def _from_sequence(self, seq):
|
||||||
"Initializes the C OGR Envelope structure from the given sequence."
|
"Initialize the C OGR Envelope structure from the given sequence."
|
||||||
self._envelope = OGREnvelope()
|
self._envelope = OGREnvelope()
|
||||||
self._envelope.MinX = seq[0]
|
self._envelope.MinX = seq[0]
|
||||||
self._envelope.MinY = seq[1]
|
self._envelope.MinY = seq[1]
|
||||||
|
@ -93,7 +93,7 @@ class Envelope:
|
||||||
|
|
||||||
def expand_to_include(self, *args):
|
def expand_to_include(self, *args):
|
||||||
"""
|
"""
|
||||||
Modifies the envelope to expand to include the boundaries of
|
Modify the envelope to expand to include the boundaries of
|
||||||
the passed-in 2-tuple (a point), 4-tuple (an extent) or
|
the passed-in 2-tuple (a point), 4-tuple (an extent) or
|
||||||
envelope.
|
envelope.
|
||||||
"""
|
"""
|
||||||
|
@ -135,42 +135,42 @@ class Envelope:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_x(self):
|
def min_x(self):
|
||||||
"Returns the value of the minimum X coordinate."
|
"Return the value of the minimum X coordinate."
|
||||||
return self._envelope.MinX
|
return self._envelope.MinX
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def min_y(self):
|
def min_y(self):
|
||||||
"Returns the value of the minimum Y coordinate."
|
"Return the value of the minimum Y coordinate."
|
||||||
return self._envelope.MinY
|
return self._envelope.MinY
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max_x(self):
|
def max_x(self):
|
||||||
"Returns the value of the maximum X coordinate."
|
"Return the value of the maximum X coordinate."
|
||||||
return self._envelope.MaxX
|
return self._envelope.MaxX
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def max_y(self):
|
def max_y(self):
|
||||||
"Returns the value of the maximum Y coordinate."
|
"Return the value of the maximum Y coordinate."
|
||||||
return self._envelope.MaxY
|
return self._envelope.MaxY
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ur(self):
|
def ur(self):
|
||||||
"Returns the upper-right coordinate."
|
"Return the upper-right coordinate."
|
||||||
return (self.max_x, self.max_y)
|
return (self.max_x, self.max_y)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ll(self):
|
def ll(self):
|
||||||
"Returns the lower-left coordinate."
|
"Return the lower-left coordinate."
|
||||||
return (self.min_x, self.min_y)
|
return (self.min_x, self.min_y)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple representing the envelope."
|
"Return a tuple representing the envelope."
|
||||||
return (self.min_x, self.min_y, self.max_x, self.max_y)
|
return (self.min_x, self.min_y, self.max_x, self.max_y)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkt(self):
|
def wkt(self):
|
||||||
"Returns WKT representing a Polygon for this envelope."
|
"Return WKT representing a Polygon for this envelope."
|
||||||
# TODO: Fix significant figures.
|
# TODO: Fix significant figures.
|
||||||
return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % \
|
return 'POLYGON((%s %s,%s %s,%s %s,%s %s,%s %s))' % \
|
||||||
(self.min_x, self.min_y, self.min_x, self.max_y,
|
(self.min_x, self.min_y, self.min_x, self.max_y,
|
||||||
|
|
|
@ -62,7 +62,7 @@ ERR_NONE = 0
|
||||||
|
|
||||||
def check_err(code, cpl=False):
|
def check_err(code, cpl=False):
|
||||||
"""
|
"""
|
||||||
Checks the given CPL/OGRERR, and raises an exception where appropriate.
|
Check the given CPL/OGRERR and raise an exception where appropriate.
|
||||||
"""
|
"""
|
||||||
err_dict = CPLERR_DICT if cpl else OGRERR_DICT
|
err_dict = CPLERR_DICT if cpl else OGRERR_DICT
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ class Feature(GDALBase):
|
||||||
|
|
||||||
def __init__(self, feat, layer):
|
def __init__(self, feat, layer):
|
||||||
"""
|
"""
|
||||||
Initializes Feature from a pointer and its Layer object.
|
Initialize Feature from a pointer and its Layer object.
|
||||||
"""
|
"""
|
||||||
if not feat:
|
if not feat:
|
||||||
raise GDALException('Cannot create OGR Feature, invalid pointer given.')
|
raise GDALException('Cannot create OGR Feature, invalid pointer given.')
|
||||||
|
@ -28,7 +28,7 @@ class Feature(GDALBase):
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"""
|
"""
|
||||||
Gets the Field object at the specified index, which may be either
|
Get the Field object at the specified index, which may be either
|
||||||
an integer or the Field's string label. Note that the Field object
|
an integer or the Field's string label. Note that the Field object
|
||||||
is not the field's _value_ -- use the `get` method instead to
|
is not the field's _value_ -- use the `get` method instead to
|
||||||
retrieve the value (e.g. an integer) instead of a Field instance.
|
retrieve the value (e.g. an integer) instead of a Field instance.
|
||||||
|
@ -42,12 +42,12 @@ class Feature(GDALBase):
|
||||||
return Field(self, i)
|
return Field(self, i)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each field in the Feature."
|
"Iterate over each field in the Feature."
|
||||||
for i in range(self.num_fields):
|
for i in range(self.num_fields):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the count of fields in this feature."
|
"Return the count of fields in this feature."
|
||||||
return self.num_fields
|
return self.num_fields
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
@ -55,7 +55,7 @@ class Feature(GDALBase):
|
||||||
return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name)
|
return 'Feature FID %d in Layer<%s>' % (self.fid, self.layer_name)
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"Does equivalence testing on the features."
|
"Do equivalence testing on the features."
|
||||||
return bool(capi.feature_equal(self.ptr, other._ptr))
|
return bool(capi.feature_equal(self.ptr, other._ptr))
|
||||||
|
|
||||||
# #### Feature Properties ####
|
# #### Feature Properties ####
|
||||||
|
@ -65,42 +65,42 @@ class Feature(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fid(self):
|
def fid(self):
|
||||||
"Returns the feature identifier."
|
"Return the feature identifier."
|
||||||
return capi.get_fid(self.ptr)
|
return capi.get_fid(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def layer_name(self):
|
def layer_name(self):
|
||||||
"Returns the name of the layer for the feature."
|
"Return the name of the layer for the feature."
|
||||||
name = capi.get_feat_name(self._layer._ldefn)
|
name = capi.get_feat_name(self._layer._ldefn)
|
||||||
return force_text(name, self.encoding, strings_only=True)
|
return force_text(name, self.encoding, strings_only=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_fields(self):
|
def num_fields(self):
|
||||||
"Returns the number of fields in the Feature."
|
"Return the number of fields in the Feature."
|
||||||
return capi.get_feat_field_count(self.ptr)
|
return capi.get_feat_field_count(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def fields(self):
|
def fields(self):
|
||||||
"Returns a list of fields in the Feature."
|
"Return a list of fields in the Feature."
|
||||||
return [capi.get_field_name(capi.get_field_defn(self._layer._ldefn, i))
|
return [capi.get_field_name(capi.get_field_defn(self._layer._ldefn, i))
|
||||||
for i in range(self.num_fields)]
|
for i in range(self.num_fields)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom(self):
|
def geom(self):
|
||||||
"Returns the OGR Geometry for this Feature."
|
"Return the OGR Geometry for this Feature."
|
||||||
# Retrieving the geometry pointer for the feature.
|
# Retrieving the geometry pointer for the feature.
|
||||||
geom_ptr = capi.get_feat_geom_ref(self.ptr)
|
geom_ptr = capi.get_feat_geom_ref(self.ptr)
|
||||||
return OGRGeometry(geom_api.clone_geom(geom_ptr))
|
return OGRGeometry(geom_api.clone_geom(geom_ptr))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_type(self):
|
def geom_type(self):
|
||||||
"Returns the OGR Geometry Type for this Feture."
|
"Return the OGR Geometry Type for this Feture."
|
||||||
return OGRGeomType(capi.get_fd_geom_type(self._layer._ldefn))
|
return OGRGeomType(capi.get_fd_geom_type(self._layer._ldefn))
|
||||||
|
|
||||||
# #### Feature Methods ####
|
# #### Feature Methods ####
|
||||||
def get(self, field):
|
def get(self, field):
|
||||||
"""
|
"""
|
||||||
Returns the value of the field, instead of an instance of the Field
|
Return the value of the field, instead of an instance of the Field
|
||||||
object. May take a string of the field name or a Field object as
|
object. May take a string of the field name or a Field object as
|
||||||
parameters.
|
parameters.
|
||||||
"""
|
"""
|
||||||
|
@ -108,7 +108,7 @@ class Feature(GDALBase):
|
||||||
return self[field_name].value
|
return self[field_name].value
|
||||||
|
|
||||||
def index(self, field_name):
|
def index(self, field_name):
|
||||||
"Returns the index of the given field name."
|
"Return the index of the given field name."
|
||||||
i = capi.get_field_index(self.ptr, force_bytes(field_name))
|
i = capi.get_field_index(self.ptr, force_bytes(field_name))
|
||||||
if i < 0:
|
if i < 0:
|
||||||
raise OGRIndexError('invalid OFT field name given: "%s"' % field_name)
|
raise OGRIndexError('invalid OFT field name given: "%s"' % field_name)
|
||||||
|
|
|
@ -13,13 +13,12 @@ from django.utils.encoding import force_text
|
||||||
# The OGR_Fld_* routines are relevant here.
|
# The OGR_Fld_* routines are relevant here.
|
||||||
class Field(GDALBase):
|
class Field(GDALBase):
|
||||||
"""
|
"""
|
||||||
This class wraps an OGR Field, and needs to be instantiated
|
Wrap an OGR Field. Needs to be instantiated from a Feature object.
|
||||||
from a Feature object.
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, feat, index):
|
def __init__(self, feat, index):
|
||||||
"""
|
"""
|
||||||
Initializes on the feature object and the integer index of
|
Initialize on the feature object and the integer index of
|
||||||
the field within the feature.
|
the field within the feature.
|
||||||
"""
|
"""
|
||||||
# Setting the feature pointer and index.
|
# Setting the feature pointer and index.
|
||||||
|
@ -41,28 +40,28 @@ class Field(GDALBase):
|
||||||
self._double = True
|
self._double = True
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns the string representation of the Field."
|
"Return the string representation of the Field."
|
||||||
return str(self.value).strip()
|
return str(self.value).strip()
|
||||||
|
|
||||||
# #### Field Methods ####
|
# #### Field Methods ####
|
||||||
def as_double(self):
|
def as_double(self):
|
||||||
"Retrieves the Field's value as a double (float)."
|
"Retrieve the Field's value as a double (float)."
|
||||||
return capi.get_field_as_double(self._feat.ptr, self._index)
|
return capi.get_field_as_double(self._feat.ptr, self._index)
|
||||||
|
|
||||||
def as_int(self, is_64=False):
|
def as_int(self, is_64=False):
|
||||||
"Retrieves the Field's value as an integer."
|
"Retrieve the Field's value as an integer."
|
||||||
if is_64:
|
if is_64:
|
||||||
return capi.get_field_as_integer64(self._feat.ptr, self._index)
|
return capi.get_field_as_integer64(self._feat.ptr, self._index)
|
||||||
else:
|
else:
|
||||||
return capi.get_field_as_integer(self._feat.ptr, self._index)
|
return capi.get_field_as_integer(self._feat.ptr, self._index)
|
||||||
|
|
||||||
def as_string(self):
|
def as_string(self):
|
||||||
"Retrieves the Field's value as a string."
|
"Retrieve the Field's value as a string."
|
||||||
string = capi.get_field_as_string(self._feat.ptr, self._index)
|
string = capi.get_field_as_string(self._feat.ptr, self._index)
|
||||||
return force_text(string, encoding=self._feat.encoding, strings_only=True)
|
return force_text(string, encoding=self._feat.encoding, strings_only=True)
|
||||||
|
|
||||||
def as_datetime(self):
|
def as_datetime(self):
|
||||||
"Retrieves the Field's value as a tuple of date & time components."
|
"Retrieve the Field's value as a tuple of date & time components."
|
||||||
yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
|
yy, mm, dd, hh, mn, ss, tz = [c_int() for i in range(7)]
|
||||||
status = capi.get_field_as_datetime(
|
status = capi.get_field_as_datetime(
|
||||||
self._feat.ptr, self._index, byref(yy), byref(mm), byref(dd),
|
self._feat.ptr, self._index, byref(yy), byref(mm), byref(dd),
|
||||||
|
@ -75,18 +74,18 @@ class Field(GDALBase):
|
||||||
# #### Field Properties ####
|
# #### Field Properties ####
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns the name of this Field."
|
"Return the name of this Field."
|
||||||
name = capi.get_field_name(self.ptr)
|
name = capi.get_field_name(self.ptr)
|
||||||
return force_text(name, encoding=self._feat.encoding, strings_only=True)
|
return force_text(name, encoding=self._feat.encoding, strings_only=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def precision(self):
|
def precision(self):
|
||||||
"Returns the precision of this Field."
|
"Return the precision of this Field."
|
||||||
return capi.get_field_precision(self.ptr)
|
return capi.get_field_precision(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def type(self):
|
def type(self):
|
||||||
"Returns the OGR type of this Field."
|
"Return the OGR type of this Field."
|
||||||
return capi.get_field_type(self.ptr)
|
return capi.get_field_type(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -96,13 +95,13 @@ class Field(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns the value of this Field."
|
"Return the value of this Field."
|
||||||
# Default is to get the field as a string.
|
# Default is to get the field as a string.
|
||||||
return self.as_string()
|
return self.as_string()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def width(self):
|
def width(self):
|
||||||
"Returns the width of this Field."
|
"Return the width of this Field."
|
||||||
return capi.get_field_width(self.ptr)
|
return capi.get_field_width(self.ptr)
|
||||||
|
|
||||||
|
|
||||||
|
@ -113,7 +112,7 @@ class OFTInteger(Field):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns an integer contained in this field."
|
"Return an integer contained in this field."
|
||||||
if self._double:
|
if self._double:
|
||||||
# If this is really from an OFTReal field with no precision,
|
# If this is really from an OFTReal field with no precision,
|
||||||
# read as a double and cast as Python int (to prevent overflow).
|
# read as a double and cast as Python int (to prevent overflow).
|
||||||
|
@ -134,7 +133,7 @@ class OFTInteger(Field):
|
||||||
class OFTReal(Field):
|
class OFTReal(Field):
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns a float contained in this field."
|
"Return a float contained in this field."
|
||||||
return self.as_double()
|
return self.as_double()
|
||||||
|
|
||||||
|
|
||||||
|
@ -155,7 +154,7 @@ class OFTBinary(Field):
|
||||||
class OFTDate(Field):
|
class OFTDate(Field):
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns a Python `date` object for the OFTDate field."
|
"Return a Python `date` object for the OFTDate field."
|
||||||
try:
|
try:
|
||||||
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
|
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
|
||||||
return date(yy.value, mm.value, dd.value)
|
return date(yy.value, mm.value, dd.value)
|
||||||
|
@ -166,7 +165,7 @@ class OFTDate(Field):
|
||||||
class OFTDateTime(Field):
|
class OFTDateTime(Field):
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns a Python `datetime` object for this OFTDateTime field."
|
"Return a Python `datetime` object for this OFTDateTime field."
|
||||||
# TODO: Adapt timezone information.
|
# TODO: Adapt timezone information.
|
||||||
# See http://lists.osgeo.org/pipermail/gdal-dev/2006-February/007990.html
|
# See http://lists.osgeo.org/pipermail/gdal-dev/2006-February/007990.html
|
||||||
# The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
|
# The `tz` variable has values of: 0=unknown, 1=localtime (ambiguous),
|
||||||
|
@ -181,7 +180,7 @@ class OFTDateTime(Field):
|
||||||
class OFTTime(Field):
|
class OFTTime(Field):
|
||||||
@property
|
@property
|
||||||
def value(self):
|
def value(self):
|
||||||
"Returns a Python `time` object for this OFTTime field."
|
"Return a Python `time` object for this OFTTime field."
|
||||||
try:
|
try:
|
||||||
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
|
yy, mm, dd, hh, mn, ss, tz = self.as_datetime()
|
||||||
return time(hh.value, mn.value, ss.value)
|
return time(hh.value, mn.value, ss.value)
|
||||||
|
|
|
@ -59,12 +59,11 @@ from django.utils.encoding import force_bytes
|
||||||
#
|
#
|
||||||
# The OGR_G_* routines are relevant here.
|
# The OGR_G_* routines are relevant here.
|
||||||
class OGRGeometry(GDALBase):
|
class OGRGeometry(GDALBase):
|
||||||
"Generally encapsulates an OGR geometry."
|
"""Encapsulate an OGR geometry."""
|
||||||
destructor = capi.destroy_geom
|
destructor = capi.destroy_geom
|
||||||
|
|
||||||
def __init__(self, geom_input, srs=None):
|
def __init__(self, geom_input, srs=None):
|
||||||
"Initializes Geometry on either WKT or an OGR pointer as input."
|
"""Initialize Geometry on either WKT or an OGR pointer as input."""
|
||||||
|
|
||||||
str_instance = isinstance(geom_input, str)
|
str_instance = isinstance(geom_input, str)
|
||||||
|
|
||||||
# If HEX, unpack input to a binary buffer.
|
# If HEX, unpack input to a binary buffer.
|
||||||
|
@ -142,7 +141,7 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bbox(cls, bbox):
|
def from_bbox(cls, bbox):
|
||||||
"Constructs a Polygon from a bounding box (4-tuple)."
|
"Construct a Polygon from a bounding box (4-tuple)."
|
||||||
x0, y0, x1, y1 = bbox
|
x0, y0, x1, y1 = bbox
|
||||||
return OGRGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
|
return OGRGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
|
||||||
x0, y0, x0, y1, x1, y1, x1, y0, x0, y0))
|
x0, y0, x0, y1, x1, y1, x1, y0, x0, y0))
|
||||||
|
@ -154,12 +153,12 @@ class OGRGeometry(GDALBase):
|
||||||
# ### Geometry set-like operations ###
|
# ### Geometry set-like operations ###
|
||||||
# g = g1 | g2
|
# g = g1 | g2
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
"Returns the union of the two geometries."
|
"Return the union of the two geometries."
|
||||||
return self.union(other)
|
return self.union(other)
|
||||||
|
|
||||||
# g = g1 & g2
|
# g = g1 & g2
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
"Returns the intersection of this Geometry and the other."
|
"Return the intersection of this Geometry and the other."
|
||||||
return self.intersection(other)
|
return self.intersection(other)
|
||||||
|
|
||||||
# g = g1 - g2
|
# g = g1 - g2
|
||||||
|
@ -186,15 +185,15 @@ class OGRGeometry(GDALBase):
|
||||||
# #### Geometry Properties ####
|
# #### Geometry Properties ####
|
||||||
@property
|
@property
|
||||||
def dimension(self):
|
def dimension(self):
|
||||||
"Returns 0 for points, 1 for lines, and 2 for surfaces."
|
"Return 0 for points, 1 for lines, and 2 for surfaces."
|
||||||
return capi.get_dims(self.ptr)
|
return capi.get_dims(self.ptr)
|
||||||
|
|
||||||
def _get_coord_dim(self):
|
def _get_coord_dim(self):
|
||||||
"Returns the coordinate dimension of the Geometry."
|
"Return the coordinate dimension of the Geometry."
|
||||||
return capi.get_coord_dim(self.ptr)
|
return capi.get_coord_dim(self.ptr)
|
||||||
|
|
||||||
def _set_coord_dim(self, dim):
|
def _set_coord_dim(self, dim):
|
||||||
"Sets the coordinate dimension of this Geometry."
|
"Set the coordinate dimension of this Geometry."
|
||||||
if dim not in (2, 3):
|
if dim not in (2, 3):
|
||||||
raise ValueError('Geometry dimension must be either 2 or 3')
|
raise ValueError('Geometry dimension must be either 2 or 3')
|
||||||
capi.set_coord_dim(self.ptr, dim)
|
capi.set_coord_dim(self.ptr, dim)
|
||||||
|
@ -203,12 +202,12 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_count(self):
|
def geom_count(self):
|
||||||
"The number of elements in this Geometry."
|
"Return the number of elements in this Geometry."
|
||||||
return capi.get_geom_count(self.ptr)
|
return capi.get_geom_count(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def point_count(self):
|
def point_count(self):
|
||||||
"Returns the number of Points in this Geometry."
|
"Return the number of Points in this Geometry."
|
||||||
return capi.get_point_count(self.ptr)
|
return capi.get_point_count(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -218,27 +217,27 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_coords(self):
|
def num_coords(self):
|
||||||
"Alais for `point_count`."
|
"Alias for `point_count`."
|
||||||
return self.point_count
|
return self.point_count
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_type(self):
|
def geom_type(self):
|
||||||
"Returns the Type for this Geometry."
|
"Return the Type for this Geometry."
|
||||||
return OGRGeomType(capi.get_geom_type(self.ptr))
|
return OGRGeomType(capi.get_geom_type(self.ptr))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_name(self):
|
def geom_name(self):
|
||||||
"Returns the Name of this Geometry."
|
"Return the Name of this Geometry."
|
||||||
return capi.get_geom_name(self.ptr)
|
return capi.get_geom_name(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def area(self):
|
def area(self):
|
||||||
"Returns the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise."
|
"Return the area for a LinearRing, Polygon, or MultiPolygon; 0 otherwise."
|
||||||
return capi.get_area(self.ptr)
|
return capi.get_area(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def envelope(self):
|
def envelope(self):
|
||||||
"Returns the envelope for this Geometry."
|
"Return the envelope for this Geometry."
|
||||||
# TODO: Fix Envelope() for Point geometries.
|
# TODO: Fix Envelope() for Point geometries.
|
||||||
return Envelope(capi.get_envelope(self.ptr, byref(OGREnvelope())))
|
return Envelope(capi.get_envelope(self.ptr, byref(OGREnvelope())))
|
||||||
|
|
||||||
|
@ -248,14 +247,14 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def extent(self):
|
def extent(self):
|
||||||
"Returns the envelope as a 4-tuple, instead of as an Envelope object."
|
"Return the envelope as a 4-tuple, instead of as an Envelope object."
|
||||||
return self.envelope.tuple
|
return self.envelope.tuple
|
||||||
|
|
||||||
# #### SpatialReference-related Properties ####
|
# #### SpatialReference-related Properties ####
|
||||||
|
|
||||||
# The SRS property
|
# The SRS property
|
||||||
def _get_srs(self):
|
def _get_srs(self):
|
||||||
"Returns the Spatial Reference for this Geometry."
|
"Return the Spatial Reference for this Geometry."
|
||||||
try:
|
try:
|
||||||
srs_ptr = capi.get_geom_srs(self.ptr)
|
srs_ptr = capi.get_geom_srs(self.ptr)
|
||||||
return SpatialReference(srs_api.clone_srs(srs_ptr))
|
return SpatialReference(srs_api.clone_srs(srs_ptr))
|
||||||
|
@ -263,7 +262,7 @@ class OGRGeometry(GDALBase):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def _set_srs(self, srs):
|
def _set_srs(self, srs):
|
||||||
"Sets the SpatialReference for this geometry."
|
"Set the SpatialReference for this geometry."
|
||||||
# Do not have to clone the `SpatialReference` object pointer because
|
# Do not have to clone the `SpatialReference` object pointer because
|
||||||
# when it is assigned to this `OGRGeometry` it's internal OGR
|
# when it is assigned to this `OGRGeometry` it's internal OGR
|
||||||
# reference count is incremented, and will likewise be released
|
# reference count is incremented, and will likewise be released
|
||||||
|
@ -303,41 +302,41 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geos(self):
|
def geos(self):
|
||||||
"Returns a GEOSGeometry object from this OGRGeometry."
|
"Return a GEOSGeometry object from this OGRGeometry."
|
||||||
from django.contrib.gis.geos import GEOSGeometry
|
from django.contrib.gis.geos import GEOSGeometry
|
||||||
return GEOSGeometry(self._geos_ptr(), self.srid)
|
return GEOSGeometry(self._geos_ptr(), self.srid)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def gml(self):
|
def gml(self):
|
||||||
"Returns the GML representation of the Geometry."
|
"Return the GML representation of the Geometry."
|
||||||
return capi.to_gml(self.ptr)
|
return capi.to_gml(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hex(self):
|
def hex(self):
|
||||||
"Returns the hexadecimal representation of the WKB (a string)."
|
"Return the hexadecimal representation of the WKB (a string)."
|
||||||
return b2a_hex(self.wkb).upper()
|
return b2a_hex(self.wkb).upper()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
"""
|
"""
|
||||||
Returns the GeoJSON representation of this Geometry.
|
Return the GeoJSON representation of this Geometry.
|
||||||
"""
|
"""
|
||||||
return capi.to_json(self.ptr)
|
return capi.to_json(self.ptr)
|
||||||
geojson = json
|
geojson = json
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML representation of the Geometry."
|
"Return the KML representation of the Geometry."
|
||||||
return capi.to_kml(self.ptr, None)
|
return capi.to_kml(self.ptr, None)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkb_size(self):
|
def wkb_size(self):
|
||||||
"Returns the size of the WKB buffer."
|
"Return the size of the WKB buffer."
|
||||||
return capi.get_wkbsize(self.ptr)
|
return capi.get_wkbsize(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkb(self):
|
def wkb(self):
|
||||||
"Returns the WKB representation of the Geometry."
|
"Return the WKB representation of the Geometry."
|
||||||
if sys.byteorder == 'little':
|
if sys.byteorder == 'little':
|
||||||
byteorder = 1 # wkbNDR (from ogr_core.h)
|
byteorder = 1 # wkbNDR (from ogr_core.h)
|
||||||
else:
|
else:
|
||||||
|
@ -351,12 +350,12 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkt(self):
|
def wkt(self):
|
||||||
"Returns the WKT representation of the Geometry."
|
"Return the WKT representation of the Geometry."
|
||||||
return capi.to_wkt(self.ptr, byref(c_char_p()))
|
return capi.to_wkt(self.ptr, byref(c_char_p()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ewkt(self):
|
def ewkt(self):
|
||||||
"Returns the EWKT representation of the Geometry."
|
"Return the EWKT representation of the Geometry."
|
||||||
srs = self.srs
|
srs = self.srs
|
||||||
if srs and srs.srid:
|
if srs and srs.srid:
|
||||||
return 'SRID=%s;%s' % (srs.srid, self.wkt)
|
return 'SRID=%s;%s' % (srs.srid, self.wkt)
|
||||||
|
@ -365,7 +364,7 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
# #### Geometry Methods ####
|
# #### Geometry Methods ####
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Clones this OGR Geometry."
|
"Clone this OGR Geometry."
|
||||||
return OGRGeometry(capi.clone_geom(self.ptr), self.srs)
|
return OGRGeometry(capi.clone_geom(self.ptr), self.srs)
|
||||||
|
|
||||||
def close_rings(self):
|
def close_rings(self):
|
||||||
|
@ -379,12 +378,11 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
def transform(self, coord_trans, clone=False):
|
def transform(self, coord_trans, clone=False):
|
||||||
"""
|
"""
|
||||||
Transforms this geometry to a different spatial reference system.
|
Transform this geometry to a different spatial reference system.
|
||||||
May take a CoordTransform object, a SpatialReference object, string
|
May take a CoordTransform object, a SpatialReference object, string
|
||||||
WKT or PROJ.4, and/or an integer SRID. By default nothing is returned
|
WKT or PROJ.4, and/or an integer SRID. By default, return nothing
|
||||||
and the geometry is transformed in-place. However, if the `clone`
|
and transform the geometry in-place. However, if the `clone` keyword is
|
||||||
keyword is set, then a transformed clone of this geometry will be
|
set, return a transformed clone of this geometry.
|
||||||
returned.
|
|
||||||
"""
|
"""
|
||||||
if clone:
|
if clone:
|
||||||
klone = self.clone()
|
klone = self.clone()
|
||||||
|
@ -416,35 +414,35 @@ class OGRGeometry(GDALBase):
|
||||||
return func(self.ptr, other.ptr)
|
return func(self.ptr, other.ptr)
|
||||||
|
|
||||||
def intersects(self, other):
|
def intersects(self, other):
|
||||||
"Returns True if this geometry intersects with the other."
|
"Return True if this geometry intersects with the other."
|
||||||
return self._topology(capi.ogr_intersects, other)
|
return self._topology(capi.ogr_intersects, other)
|
||||||
|
|
||||||
def equals(self, other):
|
def equals(self, other):
|
||||||
"Returns True if this geometry is equivalent to the other."
|
"Return True if this geometry is equivalent to the other."
|
||||||
return self._topology(capi.ogr_equals, other)
|
return self._topology(capi.ogr_equals, other)
|
||||||
|
|
||||||
def disjoint(self, other):
|
def disjoint(self, other):
|
||||||
"Returns True if this geometry and the other are spatially disjoint."
|
"Return True if this geometry and the other are spatially disjoint."
|
||||||
return self._topology(capi.ogr_disjoint, other)
|
return self._topology(capi.ogr_disjoint, other)
|
||||||
|
|
||||||
def touches(self, other):
|
def touches(self, other):
|
||||||
"Returns True if this geometry touches the other."
|
"Return True if this geometry touches the other."
|
||||||
return self._topology(capi.ogr_touches, other)
|
return self._topology(capi.ogr_touches, other)
|
||||||
|
|
||||||
def crosses(self, other):
|
def crosses(self, other):
|
||||||
"Returns True if this geometry crosses the other."
|
"Return True if this geometry crosses the other."
|
||||||
return self._topology(capi.ogr_crosses, other)
|
return self._topology(capi.ogr_crosses, other)
|
||||||
|
|
||||||
def within(self, other):
|
def within(self, other):
|
||||||
"Returns True if this geometry is within the other."
|
"Return True if this geometry is within the other."
|
||||||
return self._topology(capi.ogr_within, other)
|
return self._topology(capi.ogr_within, other)
|
||||||
|
|
||||||
def contains(self, other):
|
def contains(self, other):
|
||||||
"Returns True if this geometry contains the other."
|
"Return True if this geometry contains the other."
|
||||||
return self._topology(capi.ogr_contains, other)
|
return self._topology(capi.ogr_contains, other)
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
"Returns True if this geometry overlaps the other."
|
"Return True if this geometry overlaps the other."
|
||||||
return self._topology(capi.ogr_overlaps, other)
|
return self._topology(capi.ogr_overlaps, other)
|
||||||
|
|
||||||
# #### Geometry-generation Methods ####
|
# #### Geometry-generation Methods ####
|
||||||
|
@ -457,41 +455,41 @@ class OGRGeometry(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def boundary(self):
|
def boundary(self):
|
||||||
"Returns the boundary of this geometry."
|
"Return the boundary of this geometry."
|
||||||
return self._geomgen(capi.get_boundary)
|
return self._geomgen(capi.get_boundary)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def convex_hull(self):
|
def convex_hull(self):
|
||||||
"""
|
"""
|
||||||
Returns the smallest convex Polygon that contains all the points in
|
Return the smallest convex Polygon that contains all the points in
|
||||||
this Geometry.
|
this Geometry.
|
||||||
"""
|
"""
|
||||||
return self._geomgen(capi.geom_convex_hull)
|
return self._geomgen(capi.geom_convex_hull)
|
||||||
|
|
||||||
def difference(self, other):
|
def difference(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a new geometry consisting of the region which is the difference
|
Return a new geometry consisting of the region which is the difference
|
||||||
of this geometry and the other.
|
of this geometry and the other.
|
||||||
"""
|
"""
|
||||||
return self._geomgen(capi.geom_diff, other)
|
return self._geomgen(capi.geom_diff, other)
|
||||||
|
|
||||||
def intersection(self, other):
|
def intersection(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a new geometry consisting of the region of intersection of this
|
Return a new geometry consisting of the region of intersection of this
|
||||||
geometry and the other.
|
geometry and the other.
|
||||||
"""
|
"""
|
||||||
return self._geomgen(capi.geom_intersection, other)
|
return self._geomgen(capi.geom_intersection, other)
|
||||||
|
|
||||||
def sym_difference(self, other):
|
def sym_difference(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a new geometry which is the symmetric difference of this
|
Return a new geometry which is the symmetric difference of this
|
||||||
geometry and the other.
|
geometry and the other.
|
||||||
"""
|
"""
|
||||||
return self._geomgen(capi.geom_sym_diff, other)
|
return self._geomgen(capi.geom_sym_diff, other)
|
||||||
|
|
||||||
def union(self, other):
|
def union(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a new geometry consisting of the region which is the union of
|
Return a new geometry consisting of the region which is the union of
|
||||||
this geometry and the other.
|
this geometry and the other.
|
||||||
"""
|
"""
|
||||||
return self._geomgen(capi.geom_union, other)
|
return self._geomgen(capi.geom_union, other)
|
||||||
|
@ -510,23 +508,23 @@ class Point(OGRGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def x(self):
|
def x(self):
|
||||||
"Returns the X coordinate for this Point."
|
"Return the X coordinate for this Point."
|
||||||
return capi.getx(self.ptr, 0)
|
return capi.getx(self.ptr, 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y(self):
|
def y(self):
|
||||||
"Returns the Y coordinate for this Point."
|
"Return the Y coordinate for this Point."
|
||||||
return capi.gety(self.ptr, 0)
|
return capi.gety(self.ptr, 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Returns the Z coordinate for this Point."
|
"Return the Z coordinate for this Point."
|
||||||
if self.coord_dim == 3:
|
if self.coord_dim == 3:
|
||||||
return capi.getz(self.ptr, 0)
|
return capi.getz(self.ptr, 0)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns the tuple of this point."
|
"Return the tuple of this point."
|
||||||
if self.coord_dim == 2:
|
if self.coord_dim == 2:
|
||||||
return (self.x, self.y)
|
return (self.x, self.y)
|
||||||
elif self.coord_dim == 3:
|
elif self.coord_dim == 3:
|
||||||
|
@ -537,7 +535,7 @@ class Point(OGRGeometry):
|
||||||
class LineString(OGRGeometry):
|
class LineString(OGRGeometry):
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"Returns the Point at the given index."
|
"Return the Point at the given index."
|
||||||
if index >= 0 and index < self.point_count:
|
if index >= 0 and index < self.point_count:
|
||||||
x, y, z = c_double(), c_double(), c_double()
|
x, y, z = c_double(), c_double(), c_double()
|
||||||
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
|
capi.get_point(self.ptr, index, byref(x), byref(y), byref(z))
|
||||||
|
@ -552,17 +550,17 @@ class LineString(OGRGeometry):
|
||||||
raise OGRIndexError('index out of range: %s' % index)
|
raise OGRIndexError('index out of range: %s' % index)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each point in the LineString."
|
"Iterate over each point in the LineString."
|
||||||
for i in range(self.point_count):
|
for i in range(self.point_count):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"The length returns the number of points in the LineString."
|
"Return the number of points in the LineString."
|
||||||
return self.point_count
|
return self.point_count
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns the tuple representation of this LineString."
|
"Return the tuple representation of this LineString."
|
||||||
return tuple(self[i] for i in range(len(self)))
|
return tuple(self[i] for i in range(len(self)))
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
|
@ -575,17 +573,17 @@ class LineString(OGRGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def x(self):
|
def x(self):
|
||||||
"Returns the X coordinates in a list."
|
"Return the X coordinates in a list."
|
||||||
return self._listarr(capi.getx)
|
return self._listarr(capi.getx)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y(self):
|
def y(self):
|
||||||
"Returns the Y coordinates in a list."
|
"Return the Y coordinates in a list."
|
||||||
return self._listarr(capi.gety)
|
return self._listarr(capi.gety)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Returns the Z coordinates in a list."
|
"Return the Z coordinates in a list."
|
||||||
if self.coord_dim == 3:
|
if self.coord_dim == 3:
|
||||||
return self._listarr(capi.getz)
|
return self._listarr(capi.getz)
|
||||||
|
|
||||||
|
@ -598,16 +596,16 @@ class LinearRing(LineString):
|
||||||
class Polygon(OGRGeometry):
|
class Polygon(OGRGeometry):
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"The number of interior rings in this Polygon."
|
"Return the number of interior rings in this Polygon."
|
||||||
return self.geom_count
|
return self.geom_count
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates through each ring in the Polygon."
|
"Iterate through each ring in the Polygon."
|
||||||
for i in range(self.geom_count):
|
for i in range(self.geom_count):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"Gets the ring at the specified index."
|
"Get the ring at the specified index."
|
||||||
if index < 0 or index >= self.geom_count:
|
if index < 0 or index >= self.geom_count:
|
||||||
raise OGRIndexError('index out of range: %s' % index)
|
raise OGRIndexError('index out of range: %s' % index)
|
||||||
else:
|
else:
|
||||||
|
@ -616,25 +614,25 @@ class Polygon(OGRGeometry):
|
||||||
# Polygon Properties
|
# Polygon Properties
|
||||||
@property
|
@property
|
||||||
def shell(self):
|
def shell(self):
|
||||||
"Returns the shell of this Polygon."
|
"Return the shell of this Polygon."
|
||||||
return self[0] # First ring is the shell
|
return self[0] # First ring is the shell
|
||||||
exterior_ring = shell
|
exterior_ring = shell
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple of LinearRing coordinate tuples."
|
"Return a tuple of LinearRing coordinate tuples."
|
||||||
return tuple(self[i].tuple for i in range(self.geom_count))
|
return tuple(self[i].tuple for i in range(self.geom_count))
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def point_count(self):
|
def point_count(self):
|
||||||
"The number of Points in this Polygon."
|
"Return the number of Points in this Polygon."
|
||||||
# Summing up the number of points in each ring of the Polygon.
|
# Summing up the number of points in each ring of the Polygon.
|
||||||
return sum(self[i].point_count for i in range(self.geom_count))
|
return sum(self[i].point_count for i in range(self.geom_count))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def centroid(self):
|
def centroid(self):
|
||||||
"Returns the centroid (a Point) of this Polygon."
|
"Return the centroid (a Point) of this Polygon."
|
||||||
# The centroid is a Point, create a geometry for this.
|
# The centroid is a Point, create a geometry for this.
|
||||||
p = OGRGeometry(OGRGeomType('Point'))
|
p = OGRGeometry(OGRGeomType('Point'))
|
||||||
capi.get_centroid(self.ptr, p.ptr)
|
capi.get_centroid(self.ptr, p.ptr)
|
||||||
|
@ -646,19 +644,19 @@ class GeometryCollection(OGRGeometry):
|
||||||
"The Geometry Collection class."
|
"The Geometry Collection class."
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"Gets the Geometry at the specified index."
|
"Get the Geometry at the specified index."
|
||||||
if index < 0 or index >= self.geom_count:
|
if index < 0 or index >= self.geom_count:
|
||||||
raise OGRIndexError('index out of range: %s' % index)
|
raise OGRIndexError('index out of range: %s' % index)
|
||||||
else:
|
else:
|
||||||
return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs)
|
return OGRGeometry(capi.clone_geom(capi.get_geom_ref(self.ptr, index)), self.srs)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each Geometry."
|
"Iterate over each Geometry."
|
||||||
for i in range(self.geom_count):
|
for i in range(self.geom_count):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"The number of geometries in this Geometry Collection."
|
"Return the number of geometries in this Geometry Collection."
|
||||||
return self.geom_count
|
return self.geom_count
|
||||||
|
|
||||||
def add(self, geom):
|
def add(self, geom):
|
||||||
|
@ -677,13 +675,13 @@ class GeometryCollection(OGRGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def point_count(self):
|
def point_count(self):
|
||||||
"The number of Points in this Geometry Collection."
|
"Return the number of Points in this Geometry Collection."
|
||||||
# Summing up the number of points in each geometry in this collection
|
# Summing up the number of points in each geometry in this collection
|
||||||
return sum(self[i].point_count for i in range(self.geom_count))
|
return sum(self[i].point_count for i in range(self.geom_count))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple representation of this Geometry Collection."
|
"Return a tuple representation of this Geometry Collection."
|
||||||
return tuple(self[i].tuple for i in range(self.geom_count))
|
return tuple(self[i].tuple for i in range(self.geom_count))
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from django.contrib.gis.gdal.error import GDALException
|
||||||
|
|
||||||
|
|
||||||
class OGRGeomType:
|
class OGRGeomType:
|
||||||
"Encapsulates OGR Geometry Types."
|
"Encapsulate OGR Geometry Types."
|
||||||
|
|
||||||
wkb25bit = -2147483648
|
wkb25bit = -2147483648
|
||||||
|
|
||||||
|
@ -30,7 +30,7 @@ class OGRGeomType:
|
||||||
_str_types = {v.lower(): k for k, v in _types.items()}
|
_str_types = {v.lower(): k for k, v in _types.items()}
|
||||||
|
|
||||||
def __init__(self, type_input):
|
def __init__(self, type_input):
|
||||||
"Figures out the correct OGR Type based upon the input."
|
"Figure out the correct OGR Type based upon the input."
|
||||||
if isinstance(type_input, OGRGeomType):
|
if isinstance(type_input, OGRGeomType):
|
||||||
num = type_input.num
|
num = type_input.num
|
||||||
elif isinstance(type_input, str):
|
elif isinstance(type_input, str):
|
||||||
|
@ -51,12 +51,12 @@ class OGRGeomType:
|
||||||
self.num = num
|
self.num = num
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns the value of the name property."
|
"Return the value of the name property."
|
||||||
return self.name
|
return self.name
|
||||||
|
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""
|
"""
|
||||||
Does an equivalence test on the OGR type with the given
|
Do an equivalence test on the OGR type with the given
|
||||||
other OGRGeomType, the short-hand string, or the integer.
|
other OGRGeomType, the short-hand string, or the integer.
|
||||||
"""
|
"""
|
||||||
if isinstance(other, OGRGeomType):
|
if isinstance(other, OGRGeomType):
|
||||||
|
@ -70,12 +70,12 @@ class OGRGeomType:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns a short-hand string form of the OGR Geometry type."
|
"Return a short-hand string form of the OGR Geometry type."
|
||||||
return self._types[self.num]
|
return self._types[self.num]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def django(self):
|
def django(self):
|
||||||
"Returns the Django GeometryField for this OGR Type."
|
"Return the Django GeometryField for this OGR Type."
|
||||||
s = self.name.replace('25D', '')
|
s = self.name.replace('25D', '')
|
||||||
if s in ('LinearRing', 'None'):
|
if s in ('LinearRing', 'None'):
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -25,7 +25,7 @@ class Layer(GDALBase):
|
||||||
|
|
||||||
def __init__(self, layer_ptr, ds):
|
def __init__(self, layer_ptr, ds):
|
||||||
"""
|
"""
|
||||||
Initializes on an OGR C pointer to the Layer and the `DataSource` object
|
Initialize on an OGR C pointer to the Layer and the `DataSource` object
|
||||||
that owns this layer. The `DataSource` object is required so that a
|
that owns this layer. The `DataSource` object is required so that a
|
||||||
reference to it is kept with this Layer. This prevents garbage
|
reference to it is kept with this Layer. This prevents garbage
|
||||||
collection of the `DataSource` while this Layer is still active.
|
collection of the `DataSource` while this Layer is still active.
|
||||||
|
@ -39,7 +39,7 @@ class Layer(GDALBase):
|
||||||
self._random_read = self.test_capability(b'RandomRead')
|
self._random_read = self.test_capability(b'RandomRead')
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"Gets the Feature at the specified index."
|
"Get the Feature at the specified index."
|
||||||
if isinstance(index, int):
|
if isinstance(index, int):
|
||||||
# An integer index was given -- we cannot do a check based on the
|
# An integer index was given -- we cannot do a check based on the
|
||||||
# number of features because the beginning and ending feature IDs
|
# number of features because the beginning and ending feature IDs
|
||||||
|
@ -55,7 +55,7 @@ class Layer(GDALBase):
|
||||||
raise TypeError('Integers and slices may only be used when indexing OGR Layers.')
|
raise TypeError('Integers and slices may only be used when indexing OGR Layers.')
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each Feature in the Layer."
|
"Iterate over each Feature in the Layer."
|
||||||
# ResetReading() must be called before iteration is to begin.
|
# ResetReading() must be called before iteration is to begin.
|
||||||
capi.reset_reading(self._ptr)
|
capi.reset_reading(self._ptr)
|
||||||
for i in range(self.num_feat):
|
for i in range(self.num_feat):
|
||||||
|
@ -94,35 +94,35 @@ class Layer(GDALBase):
|
||||||
# #### Layer properties ####
|
# #### Layer properties ####
|
||||||
@property
|
@property
|
||||||
def extent(self):
|
def extent(self):
|
||||||
"Returns the extent (an Envelope) of this layer."
|
"Return the extent (an Envelope) of this layer."
|
||||||
env = OGREnvelope()
|
env = OGREnvelope()
|
||||||
capi.get_extent(self.ptr, byref(env), 1)
|
capi.get_extent(self.ptr, byref(env), 1)
|
||||||
return Envelope(env)
|
return Envelope(env)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns the name of this layer in the Data Source."
|
"Return the name of this layer in the Data Source."
|
||||||
name = capi.get_fd_name(self._ldefn)
|
name = capi.get_fd_name(self._ldefn)
|
||||||
return force_text(name, self._ds.encoding, strings_only=True)
|
return force_text(name, self._ds.encoding, strings_only=True)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_feat(self, force=1):
|
def num_feat(self, force=1):
|
||||||
"Returns the number of features in the Layer."
|
"Return the number of features in the Layer."
|
||||||
return capi.get_feature_count(self.ptr, force)
|
return capi.get_feature_count(self.ptr, force)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_fields(self):
|
def num_fields(self):
|
||||||
"Returns the number of fields in the Layer."
|
"Return the number of fields in the Layer."
|
||||||
return capi.get_field_count(self._ldefn)
|
return capi.get_field_count(self._ldefn)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_type(self):
|
def geom_type(self):
|
||||||
"Returns the geometry type (OGRGeomType) of the Layer."
|
"Return the geometry type (OGRGeomType) of the Layer."
|
||||||
return OGRGeomType(capi.get_fd_geom_type(self._ldefn))
|
return OGRGeomType(capi.get_fd_geom_type(self._ldefn))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def srs(self):
|
def srs(self):
|
||||||
"Returns the Spatial Reference used in this Layer."
|
"Return the Spatial Reference used in this Layer."
|
||||||
try:
|
try:
|
||||||
ptr = capi.get_layer_srs(self.ptr)
|
ptr = capi.get_layer_srs(self.ptr)
|
||||||
return SpatialReference(srs_api.clone_srs(ptr))
|
return SpatialReference(srs_api.clone_srs(ptr))
|
||||||
|
@ -132,7 +132,7 @@ class Layer(GDALBase):
|
||||||
@property
|
@property
|
||||||
def fields(self):
|
def fields(self):
|
||||||
"""
|
"""
|
||||||
Returns a list of string names corresponding to each of the Fields
|
Return a list of string names corresponding to each of the Fields
|
||||||
available in this Layer.
|
available in this Layer.
|
||||||
"""
|
"""
|
||||||
return [force_text(capi.get_field_name(capi.get_field_defn(self._ldefn, i)),
|
return [force_text(capi.get_field_name(capi.get_field_defn(self._ldefn, i)),
|
||||||
|
@ -142,23 +142,22 @@ class Layer(GDALBase):
|
||||||
@property
|
@property
|
||||||
def field_types(self):
|
def field_types(self):
|
||||||
"""
|
"""
|
||||||
Returns a list of the types of fields in this Layer. For example,
|
Return a list of the types of fields in this Layer. For example,
|
||||||
the list [OFTInteger, OFTReal, OFTString] would be returned for
|
return the list [OFTInteger, OFTReal, OFTString] for an OGR layer that
|
||||||
an OGR layer that had an integer, a floating-point, and string
|
has an integer, a floating-point, and string fields.
|
||||||
fields.
|
|
||||||
"""
|
"""
|
||||||
return [OGRFieldTypes[capi.get_field_type(capi.get_field_defn(self._ldefn, i))]
|
return [OGRFieldTypes[capi.get_field_type(capi.get_field_defn(self._ldefn, i))]
|
||||||
for i in range(self.num_fields)]
|
for i in range(self.num_fields)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def field_widths(self):
|
def field_widths(self):
|
||||||
"Returns a list of the maximum field widths for the features."
|
"Return a list of the maximum field widths for the features."
|
||||||
return [capi.get_field_width(capi.get_field_defn(self._ldefn, i))
|
return [capi.get_field_width(capi.get_field_defn(self._ldefn, i))
|
||||||
for i in range(self.num_fields)]
|
for i in range(self.num_fields)]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def field_precisions(self):
|
def field_precisions(self):
|
||||||
"Returns the field precisions for the features."
|
"Return the field precisions for the features."
|
||||||
return [capi.get_field_precision(capi.get_field_defn(self._ldefn, i))
|
return [capi.get_field_precision(capi.get_field_defn(self._ldefn, i))
|
||||||
for i in range(self.num_fields)]
|
for i in range(self.num_fields)]
|
||||||
|
|
||||||
|
@ -188,7 +187,7 @@ class Layer(GDALBase):
|
||||||
# #### Layer Methods ####
|
# #### Layer Methods ####
|
||||||
def get_fields(self, field_name):
|
def get_fields(self, field_name):
|
||||||
"""
|
"""
|
||||||
Returns a list containing the given field name for every Feature
|
Return a list containing the given field name for every Feature
|
||||||
in the Layer.
|
in the Layer.
|
||||||
"""
|
"""
|
||||||
if field_name not in self.fields:
|
if field_name not in self.fields:
|
||||||
|
@ -197,7 +196,7 @@ class Layer(GDALBase):
|
||||||
|
|
||||||
def get_geoms(self, geos=False):
|
def get_geoms(self, geos=False):
|
||||||
"""
|
"""
|
||||||
Returns a list containing the OGRGeometry for every Feature in
|
Return a list containing the OGRGeometry for every Feature in
|
||||||
the Layer.
|
the Layer.
|
||||||
"""
|
"""
|
||||||
if geos:
|
if geos:
|
||||||
|
@ -208,7 +207,7 @@ class Layer(GDALBase):
|
||||||
|
|
||||||
def test_capability(self, capability):
|
def test_capability(self, capability):
|
||||||
"""
|
"""
|
||||||
Returns a bool indicating whether the this Layer supports the given
|
Return a bool indicating whether the this Layer supports the given
|
||||||
capability (a string). Valid capability strings include:
|
capability (a string). Valid capability strings include:
|
||||||
'RandomRead', 'SequentialWrite', 'RandomWrite', 'FastSpatialFilter',
|
'RandomRead', 'SequentialWrite', 'RandomWrite', 'FastSpatialFilter',
|
||||||
'FastFeatureCount', 'FastGetExtent', 'CreateField', 'Transactions',
|
'FastFeatureCount', 'FastGetExtent', 'CreateField', 'Transactions',
|
||||||
|
|
|
@ -56,7 +56,7 @@ if os.name == 'nt':
|
||||||
|
|
||||||
def std_call(func):
|
def std_call(func):
|
||||||
"""
|
"""
|
||||||
Returns the correct STDCALL function for certain OSR routines on Win32
|
Return the correct STDCALL function for certain OSR routines on Win32
|
||||||
platforms.
|
platforms.
|
||||||
"""
|
"""
|
||||||
if os.name == 'nt':
|
if os.name == 'nt':
|
||||||
|
@ -67,19 +67,19 @@ def std_call(func):
|
||||||
|
|
||||||
# #### Version-information functions. ####
|
# #### Version-information functions. ####
|
||||||
|
|
||||||
# Returns GDAL library version information with the given key.
|
# Return GDAL library version information with the given key.
|
||||||
_version_info = std_call('GDALVersionInfo')
|
_version_info = std_call('GDALVersionInfo')
|
||||||
_version_info.argtypes = [c_char_p]
|
_version_info.argtypes = [c_char_p]
|
||||||
_version_info.restype = c_char_p
|
_version_info.restype = c_char_p
|
||||||
|
|
||||||
|
|
||||||
def gdal_version():
|
def gdal_version():
|
||||||
"Returns only the GDAL version number information."
|
"Return only the GDAL version number information."
|
||||||
return _version_info(b'RELEASE_NAME')
|
return _version_info(b'RELEASE_NAME')
|
||||||
|
|
||||||
|
|
||||||
def gdal_full_version():
|
def gdal_full_version():
|
||||||
"Returns the full GDAL version information."
|
"Return the full GDAL version information."
|
||||||
return _version_info('')
|
return _version_info('')
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -13,12 +13,12 @@ from django.contrib.gis.gdal.libgdal import lgdal
|
||||||
# Helper routines for retrieving pointers and/or values from
|
# Helper routines for retrieving pointers and/or values from
|
||||||
# arguments passed in by reference.
|
# arguments passed in by reference.
|
||||||
def arg_byref(args, offset=-1):
|
def arg_byref(args, offset=-1):
|
||||||
"Returns the pointer argument's by-reference value."
|
"Return the pointer argument's by-reference value."
|
||||||
return args[offset]._obj.value
|
return args[offset]._obj.value
|
||||||
|
|
||||||
|
|
||||||
def ptr_byref(args, offset=-1):
|
def ptr_byref(args, offset=-1):
|
||||||
"Returns the pointer argument passed in by-reference."
|
"Return the pointer argument passed in by-reference."
|
||||||
return args[offset]._obj
|
return args[offset]._obj
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ def check_const_string(result, func, cargs, offset=None, cpl=False):
|
||||||
|
|
||||||
def check_string(result, func, cargs, offset=-1, str_result=False):
|
def check_string(result, func, cargs, offset=-1, str_result=False):
|
||||||
"""
|
"""
|
||||||
Checks the string output returned from the given function, and frees
|
Check the string output returned from the given function, and free
|
||||||
the string pointer allocated by OGR. The `str_result` keyword
|
the string pointer allocated by OGR. The `str_result` keyword
|
||||||
may be used when the result is the string pointer, otherwise
|
may be used when the result is the string pointer, otherwise
|
||||||
the OGR error code is assumed. The `offset` keyword may be used
|
the OGR error code is assumed. The `offset` keyword may be used
|
||||||
|
@ -68,14 +68,14 @@ def check_string(result, func, cargs, offset=-1, str_result=False):
|
||||||
|
|
||||||
# ### Envelope checking ###
|
# ### Envelope checking ###
|
||||||
def check_envelope(result, func, cargs, offset=-1):
|
def check_envelope(result, func, cargs, offset=-1):
|
||||||
"Checks a function that returns an OGR Envelope by reference."
|
"Check a function that returns an OGR Envelope by reference."
|
||||||
env = ptr_byref(cargs, offset)
|
env = ptr_byref(cargs, offset)
|
||||||
return env
|
return env
|
||||||
|
|
||||||
|
|
||||||
# ### Geometry error-checking routines ###
|
# ### Geometry error-checking routines ###
|
||||||
def check_geom(result, func, cargs):
|
def check_geom(result, func, cargs):
|
||||||
"Checks a function that returns a geometry."
|
"Check a function that returns a geometry."
|
||||||
# OGR_G_Clone may return an integer, even though the
|
# OGR_G_Clone may return an integer, even though the
|
||||||
# restype is set to c_void_p
|
# restype is set to c_void_p
|
||||||
if isinstance(result, int):
|
if isinstance(result, int):
|
||||||
|
@ -86,7 +86,7 @@ def check_geom(result, func, cargs):
|
||||||
|
|
||||||
|
|
||||||
def check_geom_offset(result, func, cargs, offset=-1):
|
def check_geom_offset(result, func, cargs, offset=-1):
|
||||||
"Chcks the geometry at the given offset in the C parameter list."
|
"Check the geometry at the given offset in the C parameter list."
|
||||||
check_err(result)
|
check_err(result)
|
||||||
geom = ptr_byref(cargs, offset=offset)
|
geom = ptr_byref(cargs, offset=offset)
|
||||||
return check_geom(geom, func, cargs)
|
return check_geom(geom, func, cargs)
|
||||||
|
@ -119,7 +119,7 @@ def check_errcode(result, func, cargs, cpl=False):
|
||||||
|
|
||||||
|
|
||||||
def check_pointer(result, func, cargs):
|
def check_pointer(result, func, cargs):
|
||||||
"Makes sure the result pointer is valid."
|
"Make sure the result pointer is valid."
|
||||||
if isinstance(result, int):
|
if isinstance(result, int):
|
||||||
result = c_void_p(result)
|
result = c_void_p(result)
|
||||||
if result:
|
if result:
|
||||||
|
|
|
@ -16,7 +16,7 @@ class gdal_char_p(c_char_p):
|
||||||
|
|
||||||
|
|
||||||
def double_output(func, argtypes, errcheck=False, strarg=False, cpl=False):
|
def double_output(func, argtypes, errcheck=False, strarg=False, cpl=False):
|
||||||
"Generates a ctypes function that returns a double value."
|
"Generate a ctypes function that returns a double value."
|
||||||
func.argtypes = argtypes
|
func.argtypes = argtypes
|
||||||
func.restype = c_double
|
func.restype = c_double
|
||||||
if errcheck:
|
if errcheck:
|
||||||
|
@ -28,7 +28,7 @@ def double_output(func, argtypes, errcheck=False, strarg=False, cpl=False):
|
||||||
|
|
||||||
def geom_output(func, argtypes, offset=None):
|
def geom_output(func, argtypes, offset=None):
|
||||||
"""
|
"""
|
||||||
Generates a function that returns a Geometry either by reference
|
Generate a function that returns a Geometry either by reference
|
||||||
or directly (if the return_geom keyword is set to True).
|
or directly (if the return_geom keyword is set to True).
|
||||||
"""
|
"""
|
||||||
# Setting the argument types
|
# Setting the argument types
|
||||||
|
@ -50,7 +50,7 @@ def geom_output(func, argtypes, offset=None):
|
||||||
|
|
||||||
|
|
||||||
def int_output(func, argtypes, errcheck=None):
|
def int_output(func, argtypes, errcheck=None):
|
||||||
"Generates a ctypes function that returns an integer value."
|
"Generate a ctypes function that returns an integer value."
|
||||||
func.argtypes = argtypes
|
func.argtypes = argtypes
|
||||||
func.restype = c_int
|
func.restype = c_int
|
||||||
if errcheck:
|
if errcheck:
|
||||||
|
@ -59,7 +59,7 @@ def int_output(func, argtypes, errcheck=None):
|
||||||
|
|
||||||
|
|
||||||
def int64_output(func, argtypes):
|
def int64_output(func, argtypes):
|
||||||
"Generates a ctypes function that returns a 64-bit integer value."
|
"Generate a ctypes function that returns a 64-bit integer value."
|
||||||
func.argtypes = argtypes
|
func.argtypes = argtypes
|
||||||
func.restype = c_int64
|
func.restype = c_int64
|
||||||
return func
|
return func
|
||||||
|
@ -67,7 +67,7 @@ def int64_output(func, argtypes):
|
||||||
|
|
||||||
def srs_output(func, argtypes):
|
def srs_output(func, argtypes):
|
||||||
"""
|
"""
|
||||||
Generates a ctypes prototype for the given function with
|
Generate a ctypes prototype for the given function with
|
||||||
the given C arguments that returns a pointer to an OGR
|
the given C arguments that returns a pointer to an OGR
|
||||||
Spatial Reference System.
|
Spatial Reference System.
|
||||||
"""
|
"""
|
||||||
|
@ -96,7 +96,7 @@ def const_string_output(func, argtypes, offset=None, decoding=None, cpl=False):
|
||||||
|
|
||||||
def string_output(func, argtypes, offset=-1, str_result=False, decoding=None):
|
def string_output(func, argtypes, offset=-1, str_result=False, decoding=None):
|
||||||
"""
|
"""
|
||||||
Generates a ctypes prototype for the given function with the
|
Generate a ctypes prototype for the given function with the
|
||||||
given argument types that returns a string from a GDAL pointer.
|
given argument types that returns a string from a GDAL pointer.
|
||||||
The `const` flag indicates whether the allocated pointer should
|
The `const` flag indicates whether the allocated pointer should
|
||||||
be freed via the GDAL library routine VSIFree -- but only applies
|
be freed via the GDAL library routine VSIFree -- but only applies
|
||||||
|
|
|
@ -10,15 +10,15 @@ from django.contrib.gis.gdal.prototypes.generation import (
|
||||||
# Shortcut generation for routines with known parameters.
|
# Shortcut generation for routines with known parameters.
|
||||||
def srs_double(f):
|
def srs_double(f):
|
||||||
"""
|
"""
|
||||||
Creates a function prototype for the OSR routines that take
|
Create a function prototype for the OSR routines that take
|
||||||
the OSRSpatialReference object and
|
the OSRSpatialReference object and return a double value.
|
||||||
"""
|
"""
|
||||||
return double_output(f, [c_void_p, POINTER(c_int)], errcheck=True)
|
return double_output(f, [c_void_p, POINTER(c_int)], errcheck=True)
|
||||||
|
|
||||||
|
|
||||||
def units_func(f):
|
def units_func(f):
|
||||||
"""
|
"""
|
||||||
Creates a ctypes function prototype for OSR units functions, e.g.,
|
Create a ctypes function prototype for OSR units functions, e.g.,
|
||||||
OSRGetAngularUnits, OSRGetLinearUnits.
|
OSRGetAngularUnits, OSRGetLinearUnits.
|
||||||
"""
|
"""
|
||||||
return double_output(f, [c_void_p, POINTER(c_char_p)], strarg=True)
|
return double_output(f, [c_void_p, POINTER(c_char_p)], strarg=True)
|
||||||
|
|
|
@ -11,7 +11,7 @@ from .const import GDAL_INTEGER_TYPES, GDAL_PIXEL_TYPES, GDAL_TO_CTYPES
|
||||||
|
|
||||||
class GDALBand(GDALBase):
|
class GDALBand(GDALBase):
|
||||||
"""
|
"""
|
||||||
Wraps a GDAL raster band, needs to be obtained from a GDALRaster object.
|
Wrap a GDAL raster band, needs to be obtained from a GDALRaster object.
|
||||||
"""
|
"""
|
||||||
def __init__(self, source, index):
|
def __init__(self, source, index):
|
||||||
self.source = source
|
self.source = source
|
||||||
|
@ -28,7 +28,7 @@ class GDALBand(GDALBase):
|
||||||
@property
|
@property
|
||||||
def description(self):
|
def description(self):
|
||||||
"""
|
"""
|
||||||
Returns the description string of the band.
|
Return the description string of the band.
|
||||||
"""
|
"""
|
||||||
return force_text(capi.get_band_description(self._ptr))
|
return force_text(capi.get_band_description(self._ptr))
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class GDALBand(GDALBase):
|
||||||
@property
|
@property
|
||||||
def pixel_count(self):
|
def pixel_count(self):
|
||||||
"""
|
"""
|
||||||
Returns the total number of pixels in this band.
|
Return the total number of pixels in this band.
|
||||||
"""
|
"""
|
||||||
return self.width * self.height
|
return self.width * self.height
|
||||||
|
|
||||||
|
@ -132,7 +132,7 @@ class GDALBand(GDALBase):
|
||||||
@property
|
@property
|
||||||
def nodata_value(self):
|
def nodata_value(self):
|
||||||
"""
|
"""
|
||||||
Returns the nodata value for this band, or None if it isn't set.
|
Return the nodata value for this band, or None if it isn't set.
|
||||||
"""
|
"""
|
||||||
# Get value and nodata exists flag
|
# Get value and nodata exists flag
|
||||||
nodata_exists = c_int()
|
nodata_exists = c_int()
|
||||||
|
@ -147,7 +147,7 @@ class GDALBand(GDALBase):
|
||||||
@nodata_value.setter
|
@nodata_value.setter
|
||||||
def nodata_value(self, value):
|
def nodata_value(self, value):
|
||||||
"""
|
"""
|
||||||
Sets the nodata value for this band.
|
Set the nodata value for this band.
|
||||||
"""
|
"""
|
||||||
if value is None:
|
if value is None:
|
||||||
if not capi.delete_band_nodata_value:
|
if not capi.delete_band_nodata_value:
|
||||||
|
@ -161,7 +161,7 @@ class GDALBand(GDALBase):
|
||||||
|
|
||||||
def datatype(self, as_string=False):
|
def datatype(self, as_string=False):
|
||||||
"""
|
"""
|
||||||
Returns the GDAL Pixel Datatype for this band.
|
Return the GDAL Pixel Datatype for this band.
|
||||||
"""
|
"""
|
||||||
dtype = capi.get_band_datatype(self._ptr)
|
dtype = capi.get_band_datatype(self._ptr)
|
||||||
if as_string:
|
if as_string:
|
||||||
|
@ -170,7 +170,7 @@ class GDALBand(GDALBase):
|
||||||
|
|
||||||
def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=False):
|
def data(self, data=None, offset=None, size=None, shape=None, as_memoryview=False):
|
||||||
"""
|
"""
|
||||||
Reads or writes pixel values for this band. Blocks of data can
|
Read or writes pixel values for this band. Blocks of data can
|
||||||
be accessed by specifying the width, height and offset of the
|
be accessed by specifying the width, height and offset of the
|
||||||
desired block. The same specification can be used to update
|
desired block. The same specification can be used to update
|
||||||
parts of a raster by providing an array of values.
|
parts of a raster by providing an array of values.
|
||||||
|
|
|
@ -51,7 +51,7 @@ class TransformPoint(list):
|
||||||
|
|
||||||
class GDALRaster(GDALBase):
|
class GDALRaster(GDALBase):
|
||||||
"""
|
"""
|
||||||
Wraps a raster GDAL Data Source object.
|
Wrap a raster GDAL Data Source object.
|
||||||
"""
|
"""
|
||||||
destructor = capi.close_ds
|
destructor = capi.close_ds
|
||||||
|
|
||||||
|
@ -165,7 +165,7 @@ class GDALRaster(GDALBase):
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
Returns the name of this raster. Corresponds to filename
|
Return the name of this raster. Corresponds to filename
|
||||||
for file-based rasters.
|
for file-based rasters.
|
||||||
"""
|
"""
|
||||||
return force_text(capi.get_ds_description(self._ptr))
|
return force_text(capi.get_ds_description(self._ptr))
|
||||||
|
@ -173,7 +173,7 @@ class GDALRaster(GDALBase):
|
||||||
@cached_property
|
@cached_property
|
||||||
def driver(self):
|
def driver(self):
|
||||||
"""
|
"""
|
||||||
Returns the GDAL Driver used for this raster.
|
Return the GDAL Driver used for this raster.
|
||||||
"""
|
"""
|
||||||
ds_driver = capi.get_ds_driver(self._ptr)
|
ds_driver = capi.get_ds_driver(self._ptr)
|
||||||
return Driver(ds_driver)
|
return Driver(ds_driver)
|
||||||
|
@ -195,7 +195,7 @@ class GDALRaster(GDALBase):
|
||||||
@property
|
@property
|
||||||
def srs(self):
|
def srs(self):
|
||||||
"""
|
"""
|
||||||
Returns the SpatialReference used in this GDALRaster.
|
Return the SpatialReference used in this GDALRaster.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
wkt = capi.get_ds_projection_ref(self._ptr)
|
wkt = capi.get_ds_projection_ref(self._ptr)
|
||||||
|
@ -208,7 +208,7 @@ class GDALRaster(GDALBase):
|
||||||
@srs.setter
|
@srs.setter
|
||||||
def srs(self, value):
|
def srs(self, value):
|
||||||
"""
|
"""
|
||||||
Sets the spatial reference used in this GDALRaster. The input can be
|
Set the spatial reference used in this GDALRaster. The input can be
|
||||||
a SpatialReference or any parameter accepted by the SpatialReference
|
a SpatialReference or any parameter accepted by the SpatialReference
|
||||||
constructor.
|
constructor.
|
||||||
"""
|
"""
|
||||||
|
@ -238,8 +238,8 @@ class GDALRaster(GDALBase):
|
||||||
@property
|
@property
|
||||||
def geotransform(self):
|
def geotransform(self):
|
||||||
"""
|
"""
|
||||||
Returns the geotransform of the data source.
|
Return the geotransform of the data source.
|
||||||
Returns the default geotransform if it does not exist or has not been
|
Return the default geotransform if it does not exist or has not been
|
||||||
set previously. The default is [0.0, 1.0, 0.0, 0.0, 0.0, -1.0].
|
set previously. The default is [0.0, 1.0, 0.0, 0.0, 0.0, -1.0].
|
||||||
"""
|
"""
|
||||||
# Create empty ctypes double array for data
|
# Create empty ctypes double array for data
|
||||||
|
@ -249,7 +249,7 @@ class GDALRaster(GDALBase):
|
||||||
|
|
||||||
@geotransform.setter
|
@geotransform.setter
|
||||||
def geotransform(self, values):
|
def geotransform(self, values):
|
||||||
"Sets the geotransform for the data source."
|
"Set the geotransform for the data source."
|
||||||
if sum([isinstance(x, (int, float)) for x in values]) != 6:
|
if sum([isinstance(x, (int, float)) for x in values]) != 6:
|
||||||
raise ValueError('Geotransform must consist of 6 numeric values.')
|
raise ValueError('Geotransform must consist of 6 numeric values.')
|
||||||
# Create ctypes double array with input and write data
|
# Create ctypes double array with input and write data
|
||||||
|
@ -281,7 +281,7 @@ class GDALRaster(GDALBase):
|
||||||
@property
|
@property
|
||||||
def extent(self):
|
def extent(self):
|
||||||
"""
|
"""
|
||||||
Returns the extent as a 4-tuple (xmin, ymin, xmax, ymax).
|
Return the extent as a 4-tuple (xmin, ymin, xmax, ymax).
|
||||||
"""
|
"""
|
||||||
# Calculate boundary values based on scale and size
|
# Calculate boundary values based on scale and size
|
||||||
xval = self.origin.x + self.scale.x * self.width
|
xval = self.origin.x + self.scale.x * self.width
|
||||||
|
@ -300,7 +300,7 @@ class GDALRaster(GDALBase):
|
||||||
|
|
||||||
def warp(self, ds_input, resampling='NearestNeighbour', max_error=0.0):
|
def warp(self, ds_input, resampling='NearestNeighbour', max_error=0.0):
|
||||||
"""
|
"""
|
||||||
Returns a warped GDALRaster with the given input characteristics.
|
Return a warped GDALRaster with the given input characteristics.
|
||||||
|
|
||||||
The input is expected to be a dictionary containing the parameters
|
The input is expected to be a dictionary containing the parameters
|
||||||
of the target raster. Allowed values are width, height, SRID, origin,
|
of the target raster. Allowed values are width, height, SRID, origin,
|
||||||
|
@ -369,7 +369,7 @@ class GDALRaster(GDALBase):
|
||||||
def transform(self, srid, driver=None, name=None, resampling='NearestNeighbour',
|
def transform(self, srid, driver=None, name=None, resampling='NearestNeighbour',
|
||||||
max_error=0.0):
|
max_error=0.0):
|
||||||
"""
|
"""
|
||||||
Returns a copy of this raster reprojected into the given SRID.
|
Return a copy of this raster reprojected into the given SRID.
|
||||||
"""
|
"""
|
||||||
# Convert the resampling algorithm name into an algorithm id
|
# Convert the resampling algorithm name into an algorithm id
|
||||||
algorithm = GDAL_RESAMPLE_ALGORITHMS[resampling]
|
algorithm = GDAL_RESAMPLE_ALGORITHMS[resampling]
|
||||||
|
|
|
@ -44,7 +44,7 @@ class SpatialReference(GDALBase):
|
||||||
|
|
||||||
def __init__(self, srs_input='', srs_type='user'):
|
def __init__(self, srs_input='', srs_type='user'):
|
||||||
"""
|
"""
|
||||||
Creates a GDAL OSR Spatial Reference object from the given input.
|
Create a GDAL OSR Spatial Reference object from the given input.
|
||||||
The input may be string of OGC Well Known Text (WKT), an integer
|
The input may be string of OGC Well Known Text (WKT), an integer
|
||||||
EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand
|
EPSG code, a PROJ.4 string, and/or a projection "well known" shorthand
|
||||||
string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83').
|
string (one of 'WGS84', 'WGS72', 'NAD27', 'NAD83').
|
||||||
|
@ -93,7 +93,7 @@ class SpatialReference(GDALBase):
|
||||||
|
|
||||||
def __getitem__(self, target):
|
def __getitem__(self, target):
|
||||||
"""
|
"""
|
||||||
Returns the value of the given string attribute node, None if the node
|
Return the value of the given string attribute node, None if the node
|
||||||
doesn't exist. Can also take a tuple as a parameter, (target, child),
|
doesn't exist. Can also take a tuple as a parameter, (target, child),
|
||||||
where child is the index of the attribute in the WKT. For example:
|
where child is the index of the attribute in the WKT. For example:
|
||||||
|
|
||||||
|
@ -120,7 +120,7 @@ class SpatialReference(GDALBase):
|
||||||
return self.attr_value(target)
|
return self.attr_value(target)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"The string representation uses 'pretty' WKT."
|
"Use 'pretty' WKT."
|
||||||
return self.pretty_wkt
|
return self.pretty_wkt
|
||||||
|
|
||||||
# #### SpatialReference Methods ####
|
# #### SpatialReference Methods ####
|
||||||
|
@ -134,19 +134,19 @@ class SpatialReference(GDALBase):
|
||||||
return capi.get_attr_value(self.ptr, force_bytes(target), index)
|
return capi.get_attr_value(self.ptr, force_bytes(target), index)
|
||||||
|
|
||||||
def auth_name(self, target):
|
def auth_name(self, target):
|
||||||
"Returns the authority name for the given string target node."
|
"Return the authority name for the given string target node."
|
||||||
return capi.get_auth_name(self.ptr, force_bytes(target))
|
return capi.get_auth_name(self.ptr, force_bytes(target))
|
||||||
|
|
||||||
def auth_code(self, target):
|
def auth_code(self, target):
|
||||||
"Returns the authority code for the given string target node."
|
"Return the authority code for the given string target node."
|
||||||
return capi.get_auth_code(self.ptr, force_bytes(target))
|
return capi.get_auth_code(self.ptr, force_bytes(target))
|
||||||
|
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Returns a clone of this SpatialReference object."
|
"Return a clone of this SpatialReference object."
|
||||||
return SpatialReference(capi.clone_srs(self.ptr))
|
return SpatialReference(capi.clone_srs(self.ptr))
|
||||||
|
|
||||||
def from_esri(self):
|
def from_esri(self):
|
||||||
"Morphs this SpatialReference from ESRI's format to EPSG."
|
"Morph this SpatialReference from ESRI's format to EPSG."
|
||||||
capi.morph_from_esri(self.ptr)
|
capi.morph_from_esri(self.ptr)
|
||||||
|
|
||||||
def identify_epsg(self):
|
def identify_epsg(self):
|
||||||
|
@ -157,17 +157,17 @@ class SpatialReference(GDALBase):
|
||||||
capi.identify_epsg(self.ptr)
|
capi.identify_epsg(self.ptr)
|
||||||
|
|
||||||
def to_esri(self):
|
def to_esri(self):
|
||||||
"Morphs this SpatialReference to ESRI's format."
|
"Morph this SpatialReference to ESRI's format."
|
||||||
capi.morph_to_esri(self.ptr)
|
capi.morph_to_esri(self.ptr)
|
||||||
|
|
||||||
def validate(self):
|
def validate(self):
|
||||||
"Checks to see if the given spatial reference is valid."
|
"Check to see if the given spatial reference is valid."
|
||||||
capi.srs_validate(self.ptr)
|
capi.srs_validate(self.ptr)
|
||||||
|
|
||||||
# #### Name & SRID properties ####
|
# #### Name & SRID properties ####
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"Returns the name of this Spatial Reference."
|
"Return the name of this Spatial Reference."
|
||||||
if self.projected:
|
if self.projected:
|
||||||
return self.attr_value('PROJCS')
|
return self.attr_value('PROJCS')
|
||||||
elif self.geographic:
|
elif self.geographic:
|
||||||
|
@ -179,7 +179,7 @@ class SpatialReference(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def srid(self):
|
def srid(self):
|
||||||
"Returns the SRID of top-level authority, or None if undefined."
|
"Return the SRID of top-level authority, or None if undefined."
|
||||||
try:
|
try:
|
||||||
return int(self.attr_value('AUTHORITY', 1))
|
return int(self.attr_value('AUTHORITY', 1))
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
|
@ -188,34 +188,33 @@ class SpatialReference(GDALBase):
|
||||||
# #### Unit Properties ####
|
# #### Unit Properties ####
|
||||||
@property
|
@property
|
||||||
def linear_name(self):
|
def linear_name(self):
|
||||||
"Returns the name of the linear units."
|
"Return the name of the linear units."
|
||||||
units, name = capi.linear_units(self.ptr, byref(c_char_p()))
|
units, name = capi.linear_units(self.ptr, byref(c_char_p()))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def linear_units(self):
|
def linear_units(self):
|
||||||
"Returns the value of the linear units."
|
"Return the value of the linear units."
|
||||||
units, name = capi.linear_units(self.ptr, byref(c_char_p()))
|
units, name = capi.linear_units(self.ptr, byref(c_char_p()))
|
||||||
return units
|
return units
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def angular_name(self):
|
def angular_name(self):
|
||||||
"Returns the name of the angular units."
|
"Return the name of the angular units."
|
||||||
units, name = capi.angular_units(self.ptr, byref(c_char_p()))
|
units, name = capi.angular_units(self.ptr, byref(c_char_p()))
|
||||||
return name
|
return name
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def angular_units(self):
|
def angular_units(self):
|
||||||
"Returns the value of the angular units."
|
"Return the value of the angular units."
|
||||||
units, name = capi.angular_units(self.ptr, byref(c_char_p()))
|
units, name = capi.angular_units(self.ptr, byref(c_char_p()))
|
||||||
return units
|
return units
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def units(self):
|
def units(self):
|
||||||
"""
|
"""
|
||||||
Returns a 2-tuple of the units value and the units name,
|
Return a 2-tuple of the units value and the units name. Automatically
|
||||||
and will automatically determines whether to return the linear
|
determine whether to return the linear or angular units.
|
||||||
or angular units.
|
|
||||||
"""
|
"""
|
||||||
units, name = None, None
|
units, name = None, None
|
||||||
if self.projected or self.local:
|
if self.projected or self.local:
|
||||||
|
@ -230,83 +229,83 @@ class SpatialReference(GDALBase):
|
||||||
@property
|
@property
|
||||||
def ellipsoid(self):
|
def ellipsoid(self):
|
||||||
"""
|
"""
|
||||||
Returns a tuple of the ellipsoid parameters:
|
Return a tuple of the ellipsoid parameters:
|
||||||
(semimajor axis, semiminor axis, and inverse flattening)
|
(semimajor axis, semiminor axis, and inverse flattening)
|
||||||
"""
|
"""
|
||||||
return (self.semi_major, self.semi_minor, self.inverse_flattening)
|
return (self.semi_major, self.semi_minor, self.inverse_flattening)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def semi_major(self):
|
def semi_major(self):
|
||||||
"Returns the Semi Major Axis for this Spatial Reference."
|
"Return the Semi Major Axis for this Spatial Reference."
|
||||||
return capi.semi_major(self.ptr, byref(c_int()))
|
return capi.semi_major(self.ptr, byref(c_int()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def semi_minor(self):
|
def semi_minor(self):
|
||||||
"Returns the Semi Minor Axis for this Spatial Reference."
|
"Return the Semi Minor Axis for this Spatial Reference."
|
||||||
return capi.semi_minor(self.ptr, byref(c_int()))
|
return capi.semi_minor(self.ptr, byref(c_int()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def inverse_flattening(self):
|
def inverse_flattening(self):
|
||||||
"Returns the Inverse Flattening for this Spatial Reference."
|
"Return the Inverse Flattening for this Spatial Reference."
|
||||||
return capi.invflattening(self.ptr, byref(c_int()))
|
return capi.invflattening(self.ptr, byref(c_int()))
|
||||||
|
|
||||||
# #### Boolean Properties ####
|
# #### Boolean Properties ####
|
||||||
@property
|
@property
|
||||||
def geographic(self):
|
def geographic(self):
|
||||||
"""
|
"""
|
||||||
Returns True if this SpatialReference is geographic
|
Return True if this SpatialReference is geographic
|
||||||
(root node is GEOGCS).
|
(root node is GEOGCS).
|
||||||
"""
|
"""
|
||||||
return bool(capi.isgeographic(self.ptr))
|
return bool(capi.isgeographic(self.ptr))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def local(self):
|
def local(self):
|
||||||
"Returns True if this SpatialReference is local (root node is LOCAL_CS)."
|
"Return True if this SpatialReference is local (root node is LOCAL_CS)."
|
||||||
return bool(capi.islocal(self.ptr))
|
return bool(capi.islocal(self.ptr))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def projected(self):
|
def projected(self):
|
||||||
"""
|
"""
|
||||||
Returns True if this SpatialReference is a projected coordinate system
|
Return True if this SpatialReference is a projected coordinate system
|
||||||
(root node is PROJCS).
|
(root node is PROJCS).
|
||||||
"""
|
"""
|
||||||
return bool(capi.isprojected(self.ptr))
|
return bool(capi.isprojected(self.ptr))
|
||||||
|
|
||||||
# #### Import Routines #####
|
# #### Import Routines #####
|
||||||
def import_epsg(self, epsg):
|
def import_epsg(self, epsg):
|
||||||
"Imports the Spatial Reference from the EPSG code (an integer)."
|
"Import the Spatial Reference from the EPSG code (an integer)."
|
||||||
capi.from_epsg(self.ptr, epsg)
|
capi.from_epsg(self.ptr, epsg)
|
||||||
|
|
||||||
def import_proj(self, proj):
|
def import_proj(self, proj):
|
||||||
"Imports the Spatial Reference from a PROJ.4 string."
|
"Import the Spatial Reference from a PROJ.4 string."
|
||||||
capi.from_proj(self.ptr, proj)
|
capi.from_proj(self.ptr, proj)
|
||||||
|
|
||||||
def import_user_input(self, user_input):
|
def import_user_input(self, user_input):
|
||||||
"Imports the Spatial Reference from the given user input string."
|
"Import the Spatial Reference from the given user input string."
|
||||||
capi.from_user_input(self.ptr, force_bytes(user_input))
|
capi.from_user_input(self.ptr, force_bytes(user_input))
|
||||||
|
|
||||||
def import_wkt(self, wkt):
|
def import_wkt(self, wkt):
|
||||||
"Imports the Spatial Reference from OGC WKT (string)"
|
"Import the Spatial Reference from OGC WKT (string)"
|
||||||
capi.from_wkt(self.ptr, byref(c_char_p(force_bytes(wkt))))
|
capi.from_wkt(self.ptr, byref(c_char_p(force_bytes(wkt))))
|
||||||
|
|
||||||
def import_xml(self, xml):
|
def import_xml(self, xml):
|
||||||
"Imports the Spatial Reference from an XML string."
|
"Import the Spatial Reference from an XML string."
|
||||||
capi.from_xml(self.ptr, xml)
|
capi.from_xml(self.ptr, xml)
|
||||||
|
|
||||||
# #### Export Properties ####
|
# #### Export Properties ####
|
||||||
@property
|
@property
|
||||||
def wkt(self):
|
def wkt(self):
|
||||||
"Returns the WKT representation of this Spatial Reference."
|
"Return the WKT representation of this Spatial Reference."
|
||||||
return capi.to_wkt(self.ptr, byref(c_char_p()))
|
return capi.to_wkt(self.ptr, byref(c_char_p()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def pretty_wkt(self, simplify=0):
|
def pretty_wkt(self, simplify=0):
|
||||||
"Returns the 'pretty' representation of the WKT."
|
"Return the 'pretty' representation of the WKT."
|
||||||
return capi.to_pretty_wkt(self.ptr, byref(c_char_p()), simplify)
|
return capi.to_pretty_wkt(self.ptr, byref(c_char_p()), simplify)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def proj(self):
|
def proj(self):
|
||||||
"Returns the PROJ.4 representation for this Spatial Reference."
|
"Return the PROJ.4 representation for this Spatial Reference."
|
||||||
return capi.to_proj(self.ptr, byref(c_char_p()))
|
return capi.to_proj(self.ptr, byref(c_char_p()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -316,7 +315,7 @@ class SpatialReference(GDALBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def xml(self, dialect=''):
|
def xml(self, dialect=''):
|
||||||
"Returns the XML representation of this Spatial Reference."
|
"Return the XML representation of this Spatial Reference."
|
||||||
return capi.to_xml(self.ptr, byref(c_char_p()), force_bytes(dialect))
|
return capi.to_xml(self.ptr, byref(c_char_p()), force_bytes(dialect))
|
||||||
|
|
||||||
|
|
||||||
|
@ -325,7 +324,7 @@ class CoordTransform(GDALBase):
|
||||||
destructor = capi.destroy_ct
|
destructor = capi.destroy_ct
|
||||||
|
|
||||||
def __init__(self, source, target):
|
def __init__(self, source, target):
|
||||||
"Initializes on a source and target SpatialReference objects."
|
"Initialize on a source and target SpatialReference objects."
|
||||||
if not isinstance(source, SpatialReference) or not isinstance(target, SpatialReference):
|
if not isinstance(source, SpatialReference) or not isinstance(target, SpatialReference):
|
||||||
raise TypeError('source and target must be of type SpatialReference')
|
raise TypeError('source and target must be of type SpatialReference')
|
||||||
self.ptr = capi.new_ct(source._ptr, target._ptr)
|
self.ptr = capi.new_ct(source._ptr, target._ptr)
|
||||||
|
|
|
@ -143,7 +143,7 @@ class GeoIP2:
|
||||||
}
|
}
|
||||||
|
|
||||||
def _check_query(self, query, country=False, city=False, city_or_country=False):
|
def _check_query(self, query, country=False, city=False, city_or_country=False):
|
||||||
"Helper routine for checking the query and database availability."
|
"Check the query and database availability."
|
||||||
# Making sure a string was passed in for the query.
|
# Making sure a string was passed in for the query.
|
||||||
if not isinstance(query, str):
|
if not isinstance(query, str):
|
||||||
raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__)
|
raise TypeError('GeoIP query must be a string, not type %s' % type(query).__name__)
|
||||||
|
|
|
@ -18,8 +18,7 @@ class GeometryCollection(GEOSGeometry):
|
||||||
_typeid = 7
|
_typeid = 7
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"Initializes a Geometry Collection from a sequence of Geometry objects."
|
"Initialize a Geometry Collection from a sequence of Geometry objects."
|
||||||
|
|
||||||
# Checking the arguments
|
# Checking the arguments
|
||||||
if len(args) == 1:
|
if len(args) == 1:
|
||||||
# If only one geometry provided or a list of geometries is provided
|
# If only one geometry provided or a list of geometries is provided
|
||||||
|
@ -40,12 +39,12 @@ class GeometryCollection(GEOSGeometry):
|
||||||
super().__init__(collection, **kwargs)
|
super().__init__(collection, **kwargs)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each Geometry in the Collection."
|
"Iterate over each Geometry in the Collection."
|
||||||
for i in range(len(self)):
|
for i in range(len(self)):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of geometries in this Collection."
|
"Return the number of geometries in this Collection."
|
||||||
return self.num_geom
|
return self.num_geom
|
||||||
|
|
||||||
# ### Methods for compatibility with ListMixin ###
|
# ### Methods for compatibility with ListMixin ###
|
||||||
|
@ -63,7 +62,7 @@ class GeometryCollection(GEOSGeometry):
|
||||||
return capi.get_geomn(self.ptr, index)
|
return capi.get_geomn(self.ptr, index)
|
||||||
|
|
||||||
def _get_single_external(self, index):
|
def _get_single_external(self, index):
|
||||||
"Returns the Geometry from this Collection at the given index (0-based)."
|
"Return the Geometry from this Collection at the given index (0-based)."
|
||||||
# Checking the index and returning the corresponding GEOS geometry.
|
# Checking the index and returning the corresponding GEOS geometry.
|
||||||
return GEOSGeometry(capi.geom_clone(self._get_single_internal(index)), srid=self.srid)
|
return GEOSGeometry(capi.geom_clone(self._get_single_internal(index)), srid=self.srid)
|
||||||
|
|
||||||
|
@ -94,12 +93,12 @@ class GeometryCollection(GEOSGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML for this Geometry Collection."
|
"Return the KML for this Geometry Collection."
|
||||||
return '<MultiGeometry>%s</MultiGeometry>' % ''.join(g.kml for g in self)
|
return '<MultiGeometry>%s</MultiGeometry>' % ''.join(g.kml for g in self)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple of all the coordinates in this Geometry Collection"
|
"Return a tuple of all the coordinates in this Geometry Collection"
|
||||||
return tuple(g.tuple for g in self)
|
return tuple(g.tuple for g in self)
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
|
|
|
@ -18,34 +18,34 @@ class GEOSCoordSeq(GEOSBase):
|
||||||
ptr_type = CS_PTR
|
ptr_type = CS_PTR
|
||||||
|
|
||||||
def __init__(self, ptr, z=False):
|
def __init__(self, ptr, z=False):
|
||||||
"Initializes from a GEOS pointer."
|
"Initialize from a GEOS pointer."
|
||||||
if not isinstance(ptr, CS_PTR):
|
if not isinstance(ptr, CS_PTR):
|
||||||
raise TypeError('Coordinate sequence should initialize with a CS_PTR.')
|
raise TypeError('Coordinate sequence should initialize with a CS_PTR.')
|
||||||
self._ptr = ptr
|
self._ptr = ptr
|
||||||
self._z = z
|
self._z = z
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each point in the coordinate sequence."
|
"Iterate over each point in the coordinate sequence."
|
||||||
for i in range(self.size):
|
for i in range(self.size):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of points in the coordinate sequence."
|
"Return the number of points in the coordinate sequence."
|
||||||
return int(self.size)
|
return int(self.size)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"Returns the string representation of the coordinate sequence."
|
"Return the string representation of the coordinate sequence."
|
||||||
return str(self.tuple)
|
return str(self.tuple)
|
||||||
|
|
||||||
def __getitem__(self, index):
|
def __getitem__(self, index):
|
||||||
"Returns the coordinate sequence value at the given index."
|
"Return the coordinate sequence value at the given index."
|
||||||
coords = [self.getX(index), self.getY(index)]
|
coords = [self.getX(index), self.getY(index)]
|
||||||
if self.dims == 3 and self._z:
|
if self.dims == 3 and self._z:
|
||||||
coords.append(self.getZ(index))
|
coords.append(self.getZ(index))
|
||||||
return tuple(coords)
|
return tuple(coords)
|
||||||
|
|
||||||
def __setitem__(self, index, value):
|
def __setitem__(self, index, value):
|
||||||
"Sets the coordinate sequence value at the given index."
|
"Set the coordinate sequence value at the given index."
|
||||||
# Checking the input value
|
# Checking the input value
|
||||||
if isinstance(value, (list, tuple)):
|
if isinstance(value, (list, tuple)):
|
||||||
pass
|
pass
|
||||||
|
@ -70,25 +70,25 @@ class GEOSCoordSeq(GEOSBase):
|
||||||
|
|
||||||
# #### Internal Routines ####
|
# #### Internal Routines ####
|
||||||
def _checkindex(self, index):
|
def _checkindex(self, index):
|
||||||
"Checks the given index."
|
"Check the given index."
|
||||||
sz = self.size
|
sz = self.size
|
||||||
if (sz < 1) or (index < 0) or (index >= sz):
|
if (sz < 1) or (index < 0) or (index >= sz):
|
||||||
raise IndexError('invalid GEOS Geometry index: %s' % index)
|
raise IndexError('invalid GEOS Geometry index: %s' % index)
|
||||||
|
|
||||||
def _checkdim(self, dim):
|
def _checkdim(self, dim):
|
||||||
"Checks the given dimension."
|
"Check the given dimension."
|
||||||
if dim < 0 or dim > 2:
|
if dim < 0 or dim > 2:
|
||||||
raise GEOSException('invalid ordinate dimension "%d"' % dim)
|
raise GEOSException('invalid ordinate dimension "%d"' % dim)
|
||||||
|
|
||||||
# #### Ordinate getting and setting routines ####
|
# #### Ordinate getting and setting routines ####
|
||||||
def getOrdinate(self, dimension, index):
|
def getOrdinate(self, dimension, index):
|
||||||
"Returns the value for the given dimension and index."
|
"Return the value for the given dimension and index."
|
||||||
self._checkindex(index)
|
self._checkindex(index)
|
||||||
self._checkdim(dimension)
|
self._checkdim(dimension)
|
||||||
return capi.cs_getordinate(self.ptr, index, dimension, byref(c_double()))
|
return capi.cs_getordinate(self.ptr, index, dimension, byref(c_double()))
|
||||||
|
|
||||||
def setOrdinate(self, dimension, index, value):
|
def setOrdinate(self, dimension, index, value):
|
||||||
"Sets the value for the given dimension and index."
|
"Set the value for the given dimension and index."
|
||||||
self._checkindex(index)
|
self._checkindex(index)
|
||||||
self._checkdim(dimension)
|
self._checkdim(dimension)
|
||||||
capi.cs_setordinate(self.ptr, index, dimension, value)
|
capi.cs_setordinate(self.ptr, index, dimension, value)
|
||||||
|
@ -120,30 +120,30 @@ class GEOSCoordSeq(GEOSBase):
|
||||||
# ### Dimensions ###
|
# ### Dimensions ###
|
||||||
@property
|
@property
|
||||||
def size(self):
|
def size(self):
|
||||||
"Returns the size of this coordinate sequence."
|
"Return the size of this coordinate sequence."
|
||||||
return capi.cs_getsize(self.ptr, byref(c_uint()))
|
return capi.cs_getsize(self.ptr, byref(c_uint()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dims(self):
|
def dims(self):
|
||||||
"Returns the dimensions of this coordinate sequence."
|
"Return the dimensions of this coordinate sequence."
|
||||||
return capi.cs_getdims(self.ptr, byref(c_uint()))
|
return capi.cs_getdims(self.ptr, byref(c_uint()))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasz(self):
|
def hasz(self):
|
||||||
"""
|
"""
|
||||||
Returns whether this coordinate sequence is 3D. This property value is
|
Return whether this coordinate sequence is 3D. This property value is
|
||||||
inherited from the parent Geometry.
|
inherited from the parent Geometry.
|
||||||
"""
|
"""
|
||||||
return self._z
|
return self._z
|
||||||
|
|
||||||
# ### Other Methods ###
|
# ### Other Methods ###
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Clones this coordinate sequence."
|
"Clone this coordinate sequence."
|
||||||
return GEOSCoordSeq(capi.cs_clone(self.ptr), self.hasz)
|
return GEOSCoordSeq(capi.cs_clone(self.ptr), self.hasz)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML representation for the coordinates."
|
"Return the KML representation for the coordinates."
|
||||||
# Getting the substitution string depending on whether the coordinates have
|
# Getting the substitution string depending on whether the coordinates have
|
||||||
# a Z dimension.
|
# a Z dimension.
|
||||||
if self.hasz:
|
if self.hasz:
|
||||||
|
@ -155,7 +155,7 @@ class GEOSCoordSeq(GEOSBase):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple version of this coordinate sequence."
|
"Return a tuple version of this coordinate sequence."
|
||||||
n = self.size
|
n = self.size
|
||||||
if n == 1:
|
if n == 1:
|
||||||
return self[0]
|
return self[0]
|
||||||
|
|
|
@ -28,5 +28,5 @@ def fromfile(file_h):
|
||||||
|
|
||||||
|
|
||||||
def fromstr(string, **kwargs):
|
def fromstr(string, **kwargs):
|
||||||
"Given a string value, returns a GEOSGeometry object."
|
"Given a string value, return a GEOSGeometry object."
|
||||||
return GEOSGeometry(string, **kwargs)
|
return GEOSGeometry(string, **kwargs)
|
||||||
|
|
|
@ -85,7 +85,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
self._post_init(srid)
|
self._post_init(srid)
|
||||||
|
|
||||||
def _post_init(self, srid):
|
def _post_init(self, srid):
|
||||||
"Helper routine for performing post-initialization setup."
|
"Perform post-initialization setup."
|
||||||
# Setting the SRID, if given.
|
# Setting the SRID, if given.
|
||||||
if srid and isinstance(srid, int):
|
if srid and isinstance(srid, int):
|
||||||
self.srid = srid
|
self.srid = srid
|
||||||
|
@ -118,7 +118,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def __copy__(self):
|
def __copy__(self):
|
||||||
"""
|
"""
|
||||||
Returns a clone because the copy of a GEOSGeometry may contain an
|
Return a clone because the copy of a GEOSGeometry may contain an
|
||||||
invalid pointer location if the original is garbage collected.
|
invalid pointer location if the original is garbage collected.
|
||||||
"""
|
"""
|
||||||
return self.clone()
|
return self.clone()
|
||||||
|
@ -182,12 +182,12 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
# http://lists.gispython.org/pipermail/community/2007-July/001034.html
|
# http://lists.gispython.org/pipermail/community/2007-July/001034.html
|
||||||
# g = g1 | g2
|
# g = g1 | g2
|
||||||
def __or__(self, other):
|
def __or__(self, other):
|
||||||
"Returns the union of this Geometry and the other."
|
"Return the union of this Geometry and the other."
|
||||||
return self.union(other)
|
return self.union(other)
|
||||||
|
|
||||||
# g = g1 & g2
|
# g = g1 & g2
|
||||||
def __and__(self, other):
|
def __and__(self, other):
|
||||||
"Returns the intersection of this Geometry and the other."
|
"Return the intersection of this Geometry and the other."
|
||||||
return self.intersection(other)
|
return self.intersection(other)
|
||||||
|
|
||||||
# g = g1 - g2
|
# g = g1 - g2
|
||||||
|
@ -202,7 +202,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
# #### Coordinate Sequence Routines ####
|
# #### Coordinate Sequence Routines ####
|
||||||
def _set_cs(self):
|
def _set_cs(self):
|
||||||
"Sets the coordinate sequence for this Geometry."
|
"Set the coordinate sequence for this Geometry."
|
||||||
if self.has_cs:
|
if self.has_cs:
|
||||||
self._cs = GEOSCoordSeq(capi.get_cs(self.ptr), self.hasz)
|
self._cs = GEOSCoordSeq(capi.get_cs(self.ptr), self.hasz)
|
||||||
else:
|
else:
|
||||||
|
@ -210,84 +210,84 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def coord_seq(self):
|
def coord_seq(self):
|
||||||
"Returns a clone of the coordinate sequence for this Geometry."
|
"Return a clone of the coordinate sequence for this Geometry."
|
||||||
if self.has_cs:
|
if self.has_cs:
|
||||||
return self._cs.clone()
|
return self._cs.clone()
|
||||||
|
|
||||||
# #### Geometry Info ####
|
# #### Geometry Info ####
|
||||||
@property
|
@property
|
||||||
def geom_type(self):
|
def geom_type(self):
|
||||||
"Returns a string representing the Geometry type, e.g. 'Polygon'"
|
"Return a string representing the Geometry type, e.g. 'Polygon'"
|
||||||
return capi.geos_type(self.ptr).decode()
|
return capi.geos_type(self.ptr).decode()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def geom_typeid(self):
|
def geom_typeid(self):
|
||||||
"Returns an integer representing the Geometry type."
|
"Return an integer representing the Geometry type."
|
||||||
return capi.geos_typeid(self.ptr)
|
return capi.geos_typeid(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_geom(self):
|
def num_geom(self):
|
||||||
"Returns the number of geometries in the Geometry."
|
"Return the number of geometries in the Geometry."
|
||||||
return capi.get_num_geoms(self.ptr)
|
return capi.get_num_geoms(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_coords(self):
|
def num_coords(self):
|
||||||
"Returns the number of coordinates in the Geometry."
|
"Return the number of coordinates in the Geometry."
|
||||||
return capi.get_num_coords(self.ptr)
|
return capi.get_num_coords(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def num_points(self):
|
def num_points(self):
|
||||||
"Returns the number points, or coordinates, in the Geometry."
|
"Return the number points, or coordinates, in the Geometry."
|
||||||
return self.num_coords
|
return self.num_coords
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def dims(self):
|
def dims(self):
|
||||||
"Returns the dimension of this Geometry (0=point, 1=line, 2=surface)."
|
"Return the dimension of this Geometry (0=point, 1=line, 2=surface)."
|
||||||
return capi.get_dims(self.ptr)
|
return capi.get_dims(self.ptr)
|
||||||
|
|
||||||
def normalize(self):
|
def normalize(self):
|
||||||
"Converts this Geometry to normal form (or canonical form)."
|
"Convert this Geometry to normal form (or canonical form)."
|
||||||
capi.geos_normalize(self.ptr)
|
capi.geos_normalize(self.ptr)
|
||||||
|
|
||||||
# #### Unary predicates ####
|
# #### Unary predicates ####
|
||||||
@property
|
@property
|
||||||
def empty(self):
|
def empty(self):
|
||||||
"""
|
"""
|
||||||
Returns a boolean indicating whether the set of points in this Geometry
|
Return a boolean indicating whether the set of points in this Geometry
|
||||||
are empty.
|
are empty.
|
||||||
"""
|
"""
|
||||||
return capi.geos_isempty(self.ptr)
|
return capi.geos_isempty(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hasz(self):
|
def hasz(self):
|
||||||
"Returns whether the geometry has a 3D dimension."
|
"Return whether the geometry has a 3D dimension."
|
||||||
return capi.geos_hasz(self.ptr)
|
return capi.geos_hasz(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ring(self):
|
def ring(self):
|
||||||
"Returns whether or not the geometry is a ring."
|
"Return whether or not the geometry is a ring."
|
||||||
return capi.geos_isring(self.ptr)
|
return capi.geos_isring(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def simple(self):
|
def simple(self):
|
||||||
"Returns false if the Geometry not simple."
|
"Return false if the Geometry isn't simple."
|
||||||
return capi.geos_issimple(self.ptr)
|
return capi.geos_issimple(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def valid(self):
|
def valid(self):
|
||||||
"This property tests the validity of this Geometry."
|
"Test the validity of this Geometry."
|
||||||
return capi.geos_isvalid(self.ptr)
|
return capi.geos_isvalid(self.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def valid_reason(self):
|
def valid_reason(self):
|
||||||
"""
|
"""
|
||||||
Returns a string containing the reason for any invalidity.
|
Return a string containing the reason for any invalidity.
|
||||||
"""
|
"""
|
||||||
return capi.geos_isvalidreason(self.ptr).decode()
|
return capi.geos_isvalidreason(self.ptr).decode()
|
||||||
|
|
||||||
# #### Binary predicates. ####
|
# #### Binary predicates. ####
|
||||||
def contains(self, other):
|
def contains(self, other):
|
||||||
"Returns true if other.within(this) returns true."
|
"Return true if other.within(this) returns true."
|
||||||
return capi.geos_contains(self.ptr, other.ptr)
|
return capi.geos_contains(self.ptr, other.ptr)
|
||||||
|
|
||||||
def covers(self, other):
|
def covers(self, other):
|
||||||
|
@ -300,7 +300,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def crosses(self, other):
|
def crosses(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is T*T****** (for a point and a curve,a point and an area or a line and
|
is T*T****** (for a point and a curve,a point and an area or a line and
|
||||||
an area) 0******** (for two curves).
|
an area) 0******** (for two curves).
|
||||||
"""
|
"""
|
||||||
|
@ -308,39 +308,39 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def disjoint(self, other):
|
def disjoint(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is FF*FF****.
|
is FF*FF****.
|
||||||
"""
|
"""
|
||||||
return capi.geos_disjoint(self.ptr, other.ptr)
|
return capi.geos_disjoint(self.ptr, other.ptr)
|
||||||
|
|
||||||
def equals(self, other):
|
def equals(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is T*F**FFF*.
|
is T*F**FFF*.
|
||||||
"""
|
"""
|
||||||
return capi.geos_equals(self.ptr, other.ptr)
|
return capi.geos_equals(self.ptr, other.ptr)
|
||||||
|
|
||||||
def equals_exact(self, other, tolerance=0):
|
def equals_exact(self, other, tolerance=0):
|
||||||
"""
|
"""
|
||||||
Returns true if the two Geometries are exactly equal, up to a
|
Return true if the two Geometries are exactly equal, up to a
|
||||||
specified tolerance.
|
specified tolerance.
|
||||||
"""
|
"""
|
||||||
return capi.geos_equalsexact(self.ptr, other.ptr, float(tolerance))
|
return capi.geos_equalsexact(self.ptr, other.ptr, float(tolerance))
|
||||||
|
|
||||||
def intersects(self, other):
|
def intersects(self, other):
|
||||||
"Returns true if disjoint returns false."
|
"Return true if disjoint return false."
|
||||||
return capi.geos_intersects(self.ptr, other.ptr)
|
return capi.geos_intersects(self.ptr, other.ptr)
|
||||||
|
|
||||||
def overlaps(self, other):
|
def overlaps(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is T*T***T** (for two points or two surfaces) 1*T***T** (for two curves).
|
is T*T***T** (for two points or two surfaces) 1*T***T** (for two curves).
|
||||||
"""
|
"""
|
||||||
return capi.geos_overlaps(self.ptr, other.ptr)
|
return capi.geos_overlaps(self.ptr, other.ptr)
|
||||||
|
|
||||||
def relate_pattern(self, other, pattern):
|
def relate_pattern(self, other, pattern):
|
||||||
"""
|
"""
|
||||||
Returns true if the elements in the DE-9IM intersection matrix for the
|
Return true if the elements in the DE-9IM intersection matrix for the
|
||||||
two Geometries match the elements in pattern.
|
two Geometries match the elements in pattern.
|
||||||
"""
|
"""
|
||||||
if not isinstance(pattern, str) or len(pattern) > 9:
|
if not isinstance(pattern, str) or len(pattern) > 9:
|
||||||
|
@ -349,14 +349,14 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def touches(self, other):
|
def touches(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is FT*******, F**T***** or F***T****.
|
is FT*******, F**T***** or F***T****.
|
||||||
"""
|
"""
|
||||||
return capi.geos_touches(self.ptr, other.ptr)
|
return capi.geos_touches(self.ptr, other.ptr)
|
||||||
|
|
||||||
def within(self, other):
|
def within(self, other):
|
||||||
"""
|
"""
|
||||||
Returns true if the DE-9IM intersection matrix for the two Geometries
|
Return true if the DE-9IM intersection matrix for the two Geometries
|
||||||
is T*F**F***.
|
is T*F**F***.
|
||||||
"""
|
"""
|
||||||
return capi.geos_within(self.ptr, other.ptr)
|
return capi.geos_within(self.ptr, other.ptr)
|
||||||
|
@ -364,7 +364,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
# #### SRID Routines ####
|
# #### SRID Routines ####
|
||||||
@property
|
@property
|
||||||
def srid(self):
|
def srid(self):
|
||||||
"Gets the SRID for the geometry, returns None if no SRID is set."
|
"Get the SRID for the geometry. Return None if no SRID is set."
|
||||||
s = capi.geos_get_srid(self.ptr)
|
s = capi.geos_get_srid(self.ptr)
|
||||||
if s == 0:
|
if s == 0:
|
||||||
return None
|
return None
|
||||||
|
@ -373,27 +373,27 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
@srid.setter
|
@srid.setter
|
||||||
def srid(self, srid):
|
def srid(self, srid):
|
||||||
"Sets the SRID for the geometry."
|
"Set the SRID for the geometry."
|
||||||
capi.geos_set_srid(self.ptr, 0 if srid is None else srid)
|
capi.geos_set_srid(self.ptr, 0 if srid is None else srid)
|
||||||
|
|
||||||
# #### Output Routines ####
|
# #### Output Routines ####
|
||||||
@property
|
@property
|
||||||
def ewkt(self):
|
def ewkt(self):
|
||||||
"""
|
"""
|
||||||
Returns the EWKT (SRID + WKT) of the Geometry.
|
Return the EWKT (SRID + WKT) of the Geometry.
|
||||||
"""
|
"""
|
||||||
srid = self.srid
|
srid = self.srid
|
||||||
return 'SRID=%s;%s' % (srid, self.wkt) if srid else self.wkt
|
return 'SRID=%s;%s' % (srid, self.wkt) if srid else self.wkt
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def wkt(self):
|
def wkt(self):
|
||||||
"Returns the WKT (Well-Known Text) representation of this Geometry."
|
"Return the WKT (Well-Known Text) representation of this Geometry."
|
||||||
return wkt_w(dim=3 if self.hasz else 2, trim=True).write(self).decode()
|
return wkt_w(dim=3 if self.hasz else 2, trim=True).write(self).decode()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def hex(self):
|
def hex(self):
|
||||||
"""
|
"""
|
||||||
Returns the WKB of this Geometry in hexadecimal form. Please note
|
Return the WKB of this Geometry in hexadecimal form. Please note
|
||||||
that the SRID is not included in this representation because it is not
|
that the SRID is not included in this representation because it is not
|
||||||
a part of the OGC specification (use the `hexewkb` property instead).
|
a part of the OGC specification (use the `hexewkb` property instead).
|
||||||
"""
|
"""
|
||||||
|
@ -404,7 +404,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def hexewkb(self):
|
def hexewkb(self):
|
||||||
"""
|
"""
|
||||||
Returns the EWKB of this Geometry in hexadecimal form. This is an
|
Return the EWKB of this Geometry in hexadecimal form. This is an
|
||||||
extension of the WKB specification that includes SRID value that are
|
extension of the WKB specification that includes SRID value that are
|
||||||
a part of this geometry.
|
a part of this geometry.
|
||||||
"""
|
"""
|
||||||
|
@ -413,7 +413,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def json(self):
|
def json(self):
|
||||||
"""
|
"""
|
||||||
Returns GeoJSON representation of this Geometry.
|
Return GeoJSON representation of this Geometry.
|
||||||
"""
|
"""
|
||||||
return json.dumps({'type': self.__class__.__name__, 'coordinates': self.coords})
|
return json.dumps({'type': self.__class__.__name__, 'coordinates': self.coords})
|
||||||
geojson = json
|
geojson = json
|
||||||
|
@ -421,7 +421,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def wkb(self):
|
def wkb(self):
|
||||||
"""
|
"""
|
||||||
Returns the WKB (Well-Known Binary) representation of this Geometry
|
Return the WKB (Well-Known Binary) representation of this Geometry
|
||||||
as a Python buffer. SRID and Z values are not included, use the
|
as a Python buffer. SRID and Z values are not included, use the
|
||||||
`ewkb` property instead.
|
`ewkb` property instead.
|
||||||
"""
|
"""
|
||||||
|
@ -438,14 +438,14 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML representation of this Geometry."
|
"Return the KML representation of this Geometry."
|
||||||
gtype = self.geom_type
|
gtype = self.geom_type
|
||||||
return '<%s>%s</%s>' % (gtype, self.coord_seq.kml, gtype)
|
return '<%s>%s</%s>' % (gtype, self.coord_seq.kml, gtype)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def prepared(self):
|
def prepared(self):
|
||||||
"""
|
"""
|
||||||
Returns a PreparedGeometry corresponding to this geometry -- it is
|
Return a PreparedGeometry corresponding to this geometry -- it is
|
||||||
optimized for the contains, intersects, and covers operations.
|
optimized for the contains, intersects, and covers operations.
|
||||||
"""
|
"""
|
||||||
return PreparedGeometry(self)
|
return PreparedGeometry(self)
|
||||||
|
@ -456,12 +456,12 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def ogr(self):
|
def ogr(self):
|
||||||
"Returns the OGR Geometry for this Geometry."
|
"Return the OGR Geometry for this Geometry."
|
||||||
return gdal.OGRGeometry(self._ogr_ptr(), self.srs)
|
return gdal.OGRGeometry(self._ogr_ptr(), self.srs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def srs(self):
|
def srs(self):
|
||||||
"Returns the OSR SpatialReference for SRID of this Geometry."
|
"Return the OSR SpatialReference for SRID of this Geometry."
|
||||||
if self.srid:
|
if self.srid:
|
||||||
try:
|
try:
|
||||||
return gdal.SpatialReference(self.srid)
|
return gdal.SpatialReference(self.srid)
|
||||||
|
@ -476,12 +476,11 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def transform(self, ct, clone=False):
|
def transform(self, ct, clone=False):
|
||||||
"""
|
"""
|
||||||
Requires GDAL. Transforms the geometry according to the given
|
Requires GDAL. Transform the geometry according to the given
|
||||||
transformation object, which may be an integer SRID, and WKT or
|
transformation object, which may be an integer SRID, and WKT or
|
||||||
PROJ.4 string. By default, the geometry is transformed in-place and
|
PROJ.4 string. By default, transform the geometry in-place and return
|
||||||
nothing is returned. However if the `clone` keyword is set, then this
|
nothing. However if the `clone` keyword is set, don't modify the
|
||||||
geometry will not be modified and a transformed clone will be returned
|
geometry and return a transformed clone instead.
|
||||||
instead.
|
|
||||||
"""
|
"""
|
||||||
srid = self.srid
|
srid = self.srid
|
||||||
|
|
||||||
|
@ -518,17 +517,17 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
# #### Topology Routines ####
|
# #### Topology Routines ####
|
||||||
def _topology(self, gptr):
|
def _topology(self, gptr):
|
||||||
"Helper routine to return Geometry from the given pointer."
|
"Return Geometry from the given pointer."
|
||||||
return GEOSGeometry(gptr, srid=self.srid)
|
return GEOSGeometry(gptr, srid=self.srid)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def boundary(self):
|
def boundary(self):
|
||||||
"Returns the boundary as a newly allocated Geometry object."
|
"Return the boundary as a newly allocated Geometry object."
|
||||||
return self._topology(capi.geos_boundary(self.ptr))
|
return self._topology(capi.geos_boundary(self.ptr))
|
||||||
|
|
||||||
def buffer(self, width, quadsegs=8):
|
def buffer(self, width, quadsegs=8):
|
||||||
"""
|
"""
|
||||||
Returns a geometry that represents all points whose distance from this
|
Return a geometry that represents all points whose distance from this
|
||||||
Geometry is less than or equal to distance. Calculations are in the
|
Geometry is less than or equal to distance. Calculations are in the
|
||||||
Spatial Reference System of this Geometry. The optional third parameter sets
|
Spatial Reference System of this Geometry. The optional third parameter sets
|
||||||
the number of segment used to approximate a quarter circle (defaults to 8).
|
the number of segment used to approximate a quarter circle (defaults to 8).
|
||||||
|
@ -548,14 +547,14 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def convex_hull(self):
|
def convex_hull(self):
|
||||||
"""
|
"""
|
||||||
Returns the smallest convex Polygon that contains all the points
|
Return the smallest convex Polygon that contains all the points
|
||||||
in the Geometry.
|
in the Geometry.
|
||||||
"""
|
"""
|
||||||
return self._topology(capi.geos_convexhull(self.ptr))
|
return self._topology(capi.geos_convexhull(self.ptr))
|
||||||
|
|
||||||
def difference(self, other):
|
def difference(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a Geometry representing the points making up this Geometry
|
Return a Geometry representing the points making up this Geometry
|
||||||
that do not make up other.
|
that do not make up other.
|
||||||
"""
|
"""
|
||||||
return self._topology(capi.geos_difference(self.ptr, other.ptr))
|
return self._topology(capi.geos_difference(self.ptr, other.ptr))
|
||||||
|
@ -566,29 +565,29 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
return self._topology(capi.geos_envelope(self.ptr))
|
return self._topology(capi.geos_envelope(self.ptr))
|
||||||
|
|
||||||
def intersection(self, other):
|
def intersection(self, other):
|
||||||
"Returns a Geometry representing the points shared by this Geometry and other."
|
"Return a Geometry representing the points shared by this Geometry and other."
|
||||||
return self._topology(capi.geos_intersection(self.ptr, other.ptr))
|
return self._topology(capi.geos_intersection(self.ptr, other.ptr))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def point_on_surface(self):
|
def point_on_surface(self):
|
||||||
"Computes an interior point of this Geometry."
|
"Compute an interior point of this Geometry."
|
||||||
return self._topology(capi.geos_pointonsurface(self.ptr))
|
return self._topology(capi.geos_pointonsurface(self.ptr))
|
||||||
|
|
||||||
def relate(self, other):
|
def relate(self, other):
|
||||||
"Returns the DE-9IM intersection matrix for this Geometry and the other."
|
"Return the DE-9IM intersection matrix for this Geometry and the other."
|
||||||
return capi.geos_relate(self.ptr, other.ptr).decode()
|
return capi.geos_relate(self.ptr, other.ptr).decode()
|
||||||
|
|
||||||
def simplify(self, tolerance=0.0, preserve_topology=False):
|
def simplify(self, tolerance=0.0, preserve_topology=False):
|
||||||
"""
|
"""
|
||||||
Returns the Geometry, simplified using the Douglas-Peucker algorithm
|
Return the Geometry, simplified using the Douglas-Peucker algorithm
|
||||||
to the specified tolerance (higher tolerance => less points). If no
|
to the specified tolerance (higher tolerance => less points). If no
|
||||||
tolerance provided, defaults to 0.
|
tolerance provided, defaults to 0.
|
||||||
|
|
||||||
By default, this function does not preserve topology - e.g. polygons can
|
By default, don't preserve topology - e.g. polygons can be split,
|
||||||
be split, collapse to lines or disappear holes can be created or
|
collapse to lines or disappear holes can be created or disappear, and
|
||||||
disappear, and lines can cross. By specifying preserve_topology=True,
|
lines can cross. By specifying preserve_topology=True, the result will
|
||||||
the result will have the same dimension and number of components as the
|
have the same dimension and number of components as the input. This is
|
||||||
input. This is significantly slower.
|
significantly slower.
|
||||||
"""
|
"""
|
||||||
if preserve_topology:
|
if preserve_topology:
|
||||||
return self._topology(capi.geos_preservesimplify(self.ptr, tolerance))
|
return self._topology(capi.geos_preservesimplify(self.ptr, tolerance))
|
||||||
|
@ -597,7 +596,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
|
|
||||||
def sym_difference(self, other):
|
def sym_difference(self, other):
|
||||||
"""
|
"""
|
||||||
Returns a set combining the points in this Geometry not in other,
|
Return a set combining the points in this Geometry not in other,
|
||||||
and the points in other not in this Geometry.
|
and the points in other not in this Geometry.
|
||||||
"""
|
"""
|
||||||
return self._topology(capi.geos_symdifference(self.ptr, other.ptr))
|
return self._topology(capi.geos_symdifference(self.ptr, other.ptr))
|
||||||
|
@ -608,18 +607,18 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
return self._topology(capi.geos_unary_union(self.ptr))
|
return self._topology(capi.geos_unary_union(self.ptr))
|
||||||
|
|
||||||
def union(self, other):
|
def union(self, other):
|
||||||
"Returns a Geometry representing all the points in this Geometry and other."
|
"Return a Geometry representing all the points in this Geometry and other."
|
||||||
return self._topology(capi.geos_union(self.ptr, other.ptr))
|
return self._topology(capi.geos_union(self.ptr, other.ptr))
|
||||||
|
|
||||||
# #### Other Routines ####
|
# #### Other Routines ####
|
||||||
@property
|
@property
|
||||||
def area(self):
|
def area(self):
|
||||||
"Returns the area of the Geometry."
|
"Return the area of the Geometry."
|
||||||
return capi.geos_area(self.ptr, byref(c_double()))
|
return capi.geos_area(self.ptr, byref(c_double()))
|
||||||
|
|
||||||
def distance(self, other):
|
def distance(self, other):
|
||||||
"""
|
"""
|
||||||
Returns the distance between the closest points on this Geometry
|
Return the distance between the closest points on this Geometry
|
||||||
and the other. Units will be in those of the coordinate system of
|
and the other. Units will be in those of the coordinate system of
|
||||||
the Geometry.
|
the Geometry.
|
||||||
"""
|
"""
|
||||||
|
@ -630,7 +629,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def extent(self):
|
def extent(self):
|
||||||
"""
|
"""
|
||||||
Returns the extent of this geometry as a 4-tuple, consisting of
|
Return the extent of this geometry as a 4-tuple, consisting of
|
||||||
(xmin, ymin, xmax, ymax).
|
(xmin, ymin, xmax, ymax).
|
||||||
"""
|
"""
|
||||||
from .point import Point
|
from .point import Point
|
||||||
|
@ -646,13 +645,13 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
@property
|
@property
|
||||||
def length(self):
|
def length(self):
|
||||||
"""
|
"""
|
||||||
Returns the length of this Geometry (e.g., 0 for point, or the
|
Return the length of this Geometry (e.g., 0 for point, or the
|
||||||
circumference of a Polygon).
|
circumference of a Polygon).
|
||||||
"""
|
"""
|
||||||
return capi.geos_length(self.ptr, byref(c_double()))
|
return capi.geos_length(self.ptr, byref(c_double()))
|
||||||
|
|
||||||
def clone(self):
|
def clone(self):
|
||||||
"Clones this Geometry."
|
"Clone this Geometry."
|
||||||
return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid)
|
return GEOSGeometry(capi.geom_clone(self.ptr), srid=self.srid)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -14,11 +14,11 @@ __all__ = ['WKBWriter', 'WKTWriter', 'WKBReader', 'WKTReader']
|
||||||
# Public classes for (WKB|WKT)Reader, which return GEOSGeometry
|
# Public classes for (WKB|WKT)Reader, which return GEOSGeometry
|
||||||
class WKBReader(_WKBReader):
|
class WKBReader(_WKBReader):
|
||||||
def read(self, wkb):
|
def read(self, wkb):
|
||||||
"Returns a GEOSGeometry for the given WKB buffer."
|
"Return a GEOSGeometry for the given WKB buffer."
|
||||||
return GEOSGeometry(super().read(wkb))
|
return GEOSGeometry(super().read(wkb))
|
||||||
|
|
||||||
|
|
||||||
class WKTReader(_WKTReader):
|
class WKTReader(_WKTReader):
|
||||||
def read(self, wkt):
|
def read(self, wkt):
|
||||||
"Returns a GEOSGeometry for the given WKT string."
|
"Return a GEOSGeometry for the given WKT string."
|
||||||
return GEOSGeometry(super().read(wkt))
|
return GEOSGeometry(super().read(wkt))
|
||||||
|
|
|
@ -131,7 +131,7 @@ CONTEXT_PTR = POINTER(GEOSContextHandle_t)
|
||||||
# Used specifically by the GEOSGeom_createPolygon and GEOSGeom_createCollection
|
# Used specifically by the GEOSGeom_createPolygon and GEOSGeom_createCollection
|
||||||
# GEOS routines
|
# GEOS routines
|
||||||
def get_pointer_arr(n):
|
def get_pointer_arr(n):
|
||||||
"Gets a ctypes pointer array (of length `n`) for GEOSGeom_t opaque pointer."
|
"Get a ctypes pointer array (of length `n`) for GEOSGeom_t opaque pointer."
|
||||||
GeomArr = GEOM_PTR * n
|
GeomArr = GEOM_PTR * n
|
||||||
return GeomArr()
|
return GeomArr()
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ class GEOSFuncFactory:
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
|
||||||
# Returns the string version of the GEOS library. Have to set the restype
|
# Return the string version of the GEOS library. Have to set the restype
|
||||||
# explicitly to c_char_p to ensure compatibility across 32 and 64-bit platforms.
|
# explicitly to c_char_p to ensure compatibility across 32 and 64-bit platforms.
|
||||||
geos_version = GEOSFuncFactory('GEOSversion', restype=c_char_p)
|
geos_version = GEOSFuncFactory('GEOSversion', restype=c_char_p)
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ version_regex = re.compile(
|
||||||
|
|
||||||
def geos_version_info():
|
def geos_version_info():
|
||||||
"""
|
"""
|
||||||
Returns a dictionary containing the various version metadata parsed from
|
Return a dictionary containing the various version metadata parsed from
|
||||||
the GEOS version string, including the version number, whether the version
|
the GEOS version string, including the version number, whether the version
|
||||||
is a release candidate (and what number release candidate), and the C API
|
is a release candidate (and what number release candidate), and the C API
|
||||||
version.
|
version.
|
||||||
|
|
|
@ -13,7 +13,7 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initializes on the given sequence -- may take lists, tuples, NumPy arrays
|
Initialize on the given sequence -- may take lists, tuples, NumPy arrays
|
||||||
of X,Y pairs, or Point objects. If Point objects are used, ownership is
|
of X,Y pairs, or Point objects. If Point objects are used, ownership is
|
||||||
_not_ transferred to the LineString object.
|
_not_ transferred to the LineString object.
|
||||||
|
|
||||||
|
@ -89,12 +89,12 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
|
||||||
super().__init__(self._init_func(cs.ptr), srid=srid)
|
super().__init__(self._init_func(cs.ptr), srid=srid)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Allows iteration over this LineString."
|
"Allow iteration over this LineString."
|
||||||
for i in range(len(self)):
|
for i in range(len(self)):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of points in this LineString."
|
"Return the number of points in this LineString."
|
||||||
return len(self._cs)
|
return len(self._cs)
|
||||||
|
|
||||||
def _get_single_external(self, index):
|
def _get_single_external(self, index):
|
||||||
|
@ -131,14 +131,14 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
|
||||||
# #### Sequence Properties ####
|
# #### Sequence Properties ####
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple version of the geometry from the coordinate sequence."
|
"Return a tuple version of the geometry from the coordinate sequence."
|
||||||
return self._cs.tuple
|
return self._cs.tuple
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
def _listarr(self, func):
|
def _listarr(self, func):
|
||||||
"""
|
"""
|
||||||
Internal routine that returns a sequence (list) corresponding with
|
Return a sequence (list) corresponding with the given function.
|
||||||
the given function. Will return a numpy array if possible.
|
Return a numpy array if possible.
|
||||||
"""
|
"""
|
||||||
lst = [func(i) for i in range(len(self))]
|
lst = [func(i) for i in range(len(self))]
|
||||||
if numpy:
|
if numpy:
|
||||||
|
@ -148,22 +148,22 @@ class LineString(LinearGeometryMixin, GEOSGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def array(self):
|
def array(self):
|
||||||
"Returns a numpy array for the LineString."
|
"Return a numpy array for the LineString."
|
||||||
return self._listarr(self._cs.__getitem__)
|
return self._listarr(self._cs.__getitem__)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def x(self):
|
def x(self):
|
||||||
"Returns a list or numpy array of the X variable."
|
"Return a list or numpy array of the X variable."
|
||||||
return self._listarr(self._cs.getX)
|
return self._listarr(self._cs.getX)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y(self):
|
def y(self):
|
||||||
"Returns a list or numpy array of the Y variable."
|
"Return a list or numpy array of the Y variable."
|
||||||
return self._listarr(self._cs.getY)
|
return self._listarr(self._cs.getY)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Returns a list or numpy array of the Z variable."
|
"Return a list or numpy array of the Z variable."
|
||||||
if not self.hasz:
|
if not self.hasz:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -16,9 +16,9 @@ class Point(GEOSGeometry):
|
||||||
The Point object may be initialized with either a tuple, or individual
|
The Point object may be initialized with either a tuple, or individual
|
||||||
parameters.
|
parameters.
|
||||||
|
|
||||||
For Example:
|
For example:
|
||||||
>>> p = Point((5, 23)) # 2D point, passed in as a tuple
|
>>> p = Point((5, 23)) # 2D point, passed in as a tuple
|
||||||
>>> p = Point(5, 23, 8) # 3D point, passed in with individual parameters
|
>>> p = Point(5, 23, 8) # 3D point, passed in with individual parameters
|
||||||
"""
|
"""
|
||||||
if x is None:
|
if x is None:
|
||||||
coords = []
|
coords = []
|
||||||
|
@ -81,12 +81,12 @@ class Point(GEOSGeometry):
|
||||||
self._cs.setOrdinate(index, 0, value)
|
self._cs.setOrdinate(index, 0, value)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Allows iteration over coordinates of this Point."
|
"Iterate over coordinates of this Point."
|
||||||
for i in range(len(self)):
|
for i in range(len(self)):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of dimensions for this Point (either 0, 2 or 3)."
|
"Return the number of dimensions for this Point (either 0, 2 or 3)."
|
||||||
if self.empty:
|
if self.empty:
|
||||||
return 0
|
return 0
|
||||||
if self.hasz:
|
if self.hasz:
|
||||||
|
@ -106,32 +106,32 @@ class Point(GEOSGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def x(self):
|
def x(self):
|
||||||
"Returns the X component of the Point."
|
"Return the X component of the Point."
|
||||||
return self._cs.getOrdinate(0, 0)
|
return self._cs.getOrdinate(0, 0)
|
||||||
|
|
||||||
@x.setter
|
@x.setter
|
||||||
def x(self, value):
|
def x(self, value):
|
||||||
"Sets the X component of the Point."
|
"Set the X component of the Point."
|
||||||
self._cs.setOrdinate(0, 0, value)
|
self._cs.setOrdinate(0, 0, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def y(self):
|
def y(self):
|
||||||
"Returns the Y component of the Point."
|
"Return the Y component of the Point."
|
||||||
return self._cs.getOrdinate(1, 0)
|
return self._cs.getOrdinate(1, 0)
|
||||||
|
|
||||||
@y.setter
|
@y.setter
|
||||||
def y(self, value):
|
def y(self, value):
|
||||||
"Sets the Y component of the Point."
|
"Set the Y component of the Point."
|
||||||
self._cs.setOrdinate(1, 0, value)
|
self._cs.setOrdinate(1, 0, value)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def z(self):
|
def z(self):
|
||||||
"Returns the Z component of the Point."
|
"Return the Z component of the Point."
|
||||||
return self._cs.getOrdinate(2, 0) if self.hasz else None
|
return self._cs.getOrdinate(2, 0) if self.hasz else None
|
||||||
|
|
||||||
@z.setter
|
@z.setter
|
||||||
def z(self, value):
|
def z(self, value):
|
||||||
"Sets the Z component of the Point."
|
"Set the Z component of the Point."
|
||||||
if not self.hasz:
|
if not self.hasz:
|
||||||
raise GEOSException('Cannot set Z on 2D Point.')
|
raise GEOSException('Cannot set Z on 2D Point.')
|
||||||
self._cs.setOrdinate(2, 0, value)
|
self._cs.setOrdinate(2, 0, value)
|
||||||
|
@ -139,12 +139,12 @@ class Point(GEOSGeometry):
|
||||||
# ### Tuple setting and retrieval routines. ###
|
# ### Tuple setting and retrieval routines. ###
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Returns a tuple of the point."
|
"Return a tuple of the point."
|
||||||
return self._cs.tuple
|
return self._cs.tuple
|
||||||
|
|
||||||
@tuple.setter
|
@tuple.setter
|
||||||
def tuple(self, tup):
|
def tuple(self, tup):
|
||||||
"Sets the coordinates of the point with the given tuple."
|
"Set the coordinates of the point with the given tuple."
|
||||||
self._cs[0] = tup
|
self._cs[0] = tup
|
||||||
|
|
||||||
# The tuple and coords properties
|
# The tuple and coords properties
|
||||||
|
|
|
@ -11,7 +11,7 @@ class Polygon(GEOSGeometry):
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Initializes on an exterior ring and a sequence of holes (both
|
Initialize on an exterior ring and a sequence of holes (both
|
||||||
instances may be either LinearRing instances, or a tuple/list
|
instances may be either LinearRing instances, or a tuple/list
|
||||||
that may be constructed into a LinearRing).
|
that may be constructed into a LinearRing).
|
||||||
|
|
||||||
|
@ -48,17 +48,17 @@ class Polygon(GEOSGeometry):
|
||||||
super().__init__(polygon, **kwargs)
|
super().__init__(polygon, **kwargs)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
"Iterates over each ring in the polygon."
|
"Iterate over each ring in the polygon."
|
||||||
for i in range(len(self)):
|
for i in range(len(self)):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def __len__(self):
|
def __len__(self):
|
||||||
"Returns the number of rings in this Polygon."
|
"Return the number of rings in this Polygon."
|
||||||
return self.num_interior_rings + 1
|
return self.num_interior_rings + 1
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bbox(cls, bbox):
|
def from_bbox(cls, bbox):
|
||||||
"Constructs a Polygon from a bounding box (4-tuple)."
|
"Construct a Polygon from a bounding box (4-tuple)."
|
||||||
x0, y0, x1, y1 = bbox
|
x0, y0, x1, y1 = bbox
|
||||||
for z in bbox:
|
for z in bbox:
|
||||||
if not isinstance(z, (float, int)):
|
if not isinstance(z, (float, int)):
|
||||||
|
@ -103,7 +103,7 @@ class Polygon(GEOSGeometry):
|
||||||
|
|
||||||
def _construct_ring(self, param, msg=(
|
def _construct_ring(self, param, msg=(
|
||||||
'Parameter must be a sequence of LinearRings or objects that can initialize to LinearRings')):
|
'Parameter must be a sequence of LinearRings or objects that can initialize to LinearRings')):
|
||||||
"Helper routine for trying to construct a ring from the given parameter."
|
"Try to construct a ring from the given parameter."
|
||||||
if isinstance(param, LinearRing):
|
if isinstance(param, LinearRing):
|
||||||
return param
|
return param
|
||||||
try:
|
try:
|
||||||
|
@ -124,15 +124,15 @@ class Polygon(GEOSGeometry):
|
||||||
|
|
||||||
def _get_single_internal(self, index):
|
def _get_single_internal(self, index):
|
||||||
"""
|
"""
|
||||||
Returns the ring at the specified index. The first index, 0, will
|
Return the ring at the specified index. The first index, 0, will
|
||||||
always return the exterior ring. Indices > 0 will return the
|
always return the exterior ring. Indices > 0 will return the
|
||||||
interior ring at the given index (e.g., poly[1] and poly[2] would
|
interior ring at the given index (e.g., poly[1] and poly[2] would
|
||||||
return the first and second interior ring, respectively).
|
return the first and second interior ring, respectively).
|
||||||
|
|
||||||
CAREFUL: Internal/External are not the same as Interior/Exterior!
|
CAREFUL: Internal/External are not the same as Interior/Exterior!
|
||||||
_get_single_internal returns a pointer from the existing geometries for use
|
Return a pointer from the existing geometries for use internally by the
|
||||||
internally by the object's methods. _get_single_external returns a clone
|
object's methods. _get_single_external() returns a clone of the same
|
||||||
of the same geometry for use by external code.
|
geometry for use by external code.
|
||||||
"""
|
"""
|
||||||
if index == 0:
|
if index == 0:
|
||||||
return capi.get_extring(self.ptr)
|
return capi.get_extring(self.ptr)
|
||||||
|
@ -149,16 +149,16 @@ class Polygon(GEOSGeometry):
|
||||||
# #### Polygon Properties ####
|
# #### Polygon Properties ####
|
||||||
@property
|
@property
|
||||||
def num_interior_rings(self):
|
def num_interior_rings(self):
|
||||||
"Returns the number of interior rings."
|
"Return the number of interior rings."
|
||||||
# Getting the number of rings
|
# Getting the number of rings
|
||||||
return capi.get_nrings(self.ptr)
|
return capi.get_nrings(self.ptr)
|
||||||
|
|
||||||
def _get_ext_ring(self):
|
def _get_ext_ring(self):
|
||||||
"Gets the exterior ring of the Polygon."
|
"Get the exterior ring of the Polygon."
|
||||||
return self[0]
|
return self[0]
|
||||||
|
|
||||||
def _set_ext_ring(self, ring):
|
def _set_ext_ring(self, ring):
|
||||||
"Sets the exterior ring of the Polygon."
|
"Set the exterior ring of the Polygon."
|
||||||
self[0] = ring
|
self[0] = ring
|
||||||
|
|
||||||
# Properties for the exterior ring/shell.
|
# Properties for the exterior ring/shell.
|
||||||
|
@ -167,13 +167,13 @@ class Polygon(GEOSGeometry):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def tuple(self):
|
def tuple(self):
|
||||||
"Gets the tuple for each ring in this Polygon."
|
"Get the tuple for each ring in this Polygon."
|
||||||
return tuple(self[i].tuple for i in range(len(self)))
|
return tuple(self[i].tuple for i in range(len(self)))
|
||||||
coords = tuple
|
coords = tuple
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def kml(self):
|
def kml(self):
|
||||||
"Returns the KML representation of this Polygon."
|
"Return the KML representation of this Polygon."
|
||||||
inner_kml = ''.join(
|
inner_kml = ''.join(
|
||||||
"<innerBoundaryIs>%s</innerBoundaryIs>" % self[i + 1].kml
|
"<innerBoundaryIs>%s</innerBoundaryIs>" % self[i + 1].kml
|
||||||
for i in range(self.num_interior_rings)
|
for i in range(self.num_interior_rings)
|
||||||
|
|
|
@ -8,7 +8,7 @@ from django.contrib.gis.geos.prototypes.errcheck import (
|
||||||
|
|
||||||
# ## Error-checking routines specific to coordinate sequences. ##
|
# ## Error-checking routines specific to coordinate sequences. ##
|
||||||
def check_cs_op(result, func, cargs):
|
def check_cs_op(result, func, cargs):
|
||||||
"Checks the status code of a coordinate sequence operation."
|
"Check the status code of a coordinate sequence operation."
|
||||||
if result == 0:
|
if result == 0:
|
||||||
raise GEOSException('Could not set value on coordinate sequence')
|
raise GEOSException('Could not set value on coordinate sequence')
|
||||||
else:
|
else:
|
||||||
|
@ -16,7 +16,7 @@ def check_cs_op(result, func, cargs):
|
||||||
|
|
||||||
|
|
||||||
def check_cs_get(result, func, cargs):
|
def check_cs_get(result, func, cargs):
|
||||||
"Checking the coordinate sequence retrieval."
|
"Check the coordinate sequence retrieval."
|
||||||
check_cs_op(result, func, cargs)
|
check_cs_op(result, func, cargs)
|
||||||
# Object in by reference, return its value.
|
# Object in by reference, return its value.
|
||||||
return last_arg_byref(cargs)
|
return last_arg_byref(cargs)
|
||||||
|
|
|
@ -13,12 +13,12 @@ free.argtypes = [c_void_p]
|
||||||
|
|
||||||
|
|
||||||
def last_arg_byref(args):
|
def last_arg_byref(args):
|
||||||
"Returns the last C argument's value by reference."
|
"Return the last C argument's value by reference."
|
||||||
return args[-1]._obj.value
|
return args[-1]._obj.value
|
||||||
|
|
||||||
|
|
||||||
def check_dbl(result, func, cargs):
|
def check_dbl(result, func, cargs):
|
||||||
"Checks the status code and returns the double value passed in by reference."
|
"Check the status code and returns the double value passed in by reference."
|
||||||
# Checking the status code
|
# Checking the status code
|
||||||
if result != 1:
|
if result != 1:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -22,7 +22,7 @@ class geos_char_p(c_char_p):
|
||||||
|
|
||||||
# ### ctypes factory classes ###
|
# ### ctypes factory classes ###
|
||||||
class BinConstructor(GEOSFuncFactory):
|
class BinConstructor(GEOSFuncFactory):
|
||||||
"Generates a prototype for binary construction (HEX, WKB) GEOS routines."
|
"Generate a prototype for binary construction (HEX, WKB) GEOS routines."
|
||||||
argtypes = [c_char_p, c_size_t]
|
argtypes = [c_char_p, c_size_t]
|
||||||
restype = GEOM_PTR
|
restype = GEOM_PTR
|
||||||
errcheck = staticmethod(check_geom)
|
errcheck = staticmethod(check_geom)
|
||||||
|
@ -30,7 +30,7 @@ class BinConstructor(GEOSFuncFactory):
|
||||||
|
|
||||||
# HEX & WKB output
|
# HEX & WKB output
|
||||||
class BinOutput(GEOSFuncFactory):
|
class BinOutput(GEOSFuncFactory):
|
||||||
"Generates a prototype for the routines that return a sized string."
|
"Generate a prototype for the routines that return a sized string."
|
||||||
argtypes = [GEOM_PTR, POINTER(c_size_t)]
|
argtypes = [GEOM_PTR, POINTER(c_size_t)]
|
||||||
restype = c_uchar_p
|
restype = c_uchar_p
|
||||||
errcheck = staticmethod(check_sized_string)
|
errcheck = staticmethod(check_sized_string)
|
||||||
|
|
|
@ -145,7 +145,7 @@ class _WKBReader(IOBase):
|
||||||
destructor = wkb_reader_destroy
|
destructor = wkb_reader_destroy
|
||||||
|
|
||||||
def read(self, wkb):
|
def read(self, wkb):
|
||||||
"Returns a _pointer_ to C GEOS Geometry object from the given WKB."
|
"Return a _pointer_ to C GEOS Geometry object from the given WKB."
|
||||||
if isinstance(wkb, memoryview):
|
if isinstance(wkb, memoryview):
|
||||||
wkb_s = bytes(wkb)
|
wkb_s = bytes(wkb)
|
||||||
return wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
|
return wkb_reader_read(self.ptr, wkb_s, len(wkb_s))
|
||||||
|
@ -173,7 +173,7 @@ class WKTWriter(IOBase):
|
||||||
self.outdim = dim
|
self.outdim = dim
|
||||||
|
|
||||||
def write(self, geom):
|
def write(self, geom):
|
||||||
"Returns the WKT representation of the given geometry."
|
"Return the WKT representation of the given geometry."
|
||||||
return wkt_writer_write(self.ptr, geom.ptr)
|
return wkt_writer_write(self.ptr, geom.ptr)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
|
@ -231,7 +231,7 @@ class WKBWriter(IOBase):
|
||||||
return geom
|
return geom
|
||||||
|
|
||||||
def write(self, geom):
|
def write(self, geom):
|
||||||
"Returns the WKB representation of the given geometry."
|
"Return the WKB representation of the given geometry."
|
||||||
from django.contrib.gis.geos import Polygon
|
from django.contrib.gis.geos import Polygon
|
||||||
geom = self._handle_empty_point(geom)
|
geom = self._handle_empty_point(geom)
|
||||||
wkb = wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t()))
|
wkb = wkb_writer_write(self.ptr, geom.ptr, byref(c_size_t()))
|
||||||
|
@ -242,7 +242,7 @@ class WKBWriter(IOBase):
|
||||||
return memoryview(wkb)
|
return memoryview(wkb)
|
||||||
|
|
||||||
def write_hex(self, geom):
|
def write_hex(self, geom):
|
||||||
"Returns the HEXEWKB representation of the given geometry."
|
"Return the HEXEWKB representation of the given geometry."
|
||||||
from django.contrib.gis.geos.polygon import Polygon
|
from django.contrib.gis.geos.polygon import Polygon
|
||||||
geom = self._handle_empty_point(geom)
|
geom = self._handle_empty_point(geom)
|
||||||
wkb = wkb_writer_write_hex(self.ptr, geom.ptr, byref(c_size_t()))
|
wkb = wkb_writer_write_hex(self.ptr, geom.ptr, byref(c_size_t()))
|
||||||
|
|
|
@ -7,9 +7,7 @@ from django.contrib.gis.geos.libgeos import (
|
||||||
|
|
||||||
|
|
||||||
class GEOSContextHandle(GEOSBase):
|
class GEOSContextHandle(GEOSBase):
|
||||||
"""
|
"""Represent a GEOS context handle."""
|
||||||
Python object representing a GEOS context handle.
|
|
||||||
"""
|
|
||||||
ptr_type = CONTEXT_PTR
|
ptr_type = CONTEXT_PTR
|
||||||
destructor = lgeos.finishGEOS_r
|
destructor = lgeos.finishGEOS_r
|
||||||
|
|
||||||
|
@ -30,8 +28,8 @@ thread_context = GEOSContext()
|
||||||
|
|
||||||
class GEOSFunc:
|
class GEOSFunc:
|
||||||
"""
|
"""
|
||||||
Class that serves as a wrapper for GEOS C Functions, and will
|
Serve as a wrapper for GEOS C Functions. Use thread-safe function
|
||||||
use thread-safe function variants when available.
|
variants when available.
|
||||||
"""
|
"""
|
||||||
def __init__(self, func_name):
|
def __init__(self, func_name):
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -202,9 +202,9 @@ class MeasureBase:
|
||||||
@classmethod
|
@classmethod
|
||||||
def unit_attname(cls, unit_str):
|
def unit_attname(cls, unit_str):
|
||||||
"""
|
"""
|
||||||
Retrieves the unit attribute name for the given unit string.
|
Retrieve the unit attribute name for the given unit string.
|
||||||
For example, if the given unit string is 'metre', 'm' would be returned.
|
For example, if the given unit string is 'metre', return 'm'.
|
||||||
An exception is raised if an attribute cannot be found.
|
Raise an exception if an attribute cannot be found.
|
||||||
"""
|
"""
|
||||||
lower = unit_str.lower()
|
lower = unit_str.lower()
|
||||||
if unit_str in cls.UNITS:
|
if unit_str in cls.UNITS:
|
||||||
|
|
|
@ -13,7 +13,7 @@ except ImportError:
|
||||||
|
|
||||||
|
|
||||||
def compress_kml(kml):
|
def compress_kml(kml):
|
||||||
"Returns compressed KMZ from the given KML string."
|
"Return compressed KMZ from the given KML string."
|
||||||
kmz = BytesIO()
|
kmz = BytesIO()
|
||||||
with zipfile.ZipFile(kmz, 'a', zipfile.ZIP_DEFLATED) as zf:
|
with zipfile.ZipFile(kmz, 'a', zipfile.ZIP_DEFLATED) as zf:
|
||||||
zf.writestr('doc.kml', kml.encode(settings.DEFAULT_CHARSET))
|
zf.writestr('doc.kml', kml.encode(settings.DEFAULT_CHARSET))
|
||||||
|
@ -22,7 +22,7 @@ def compress_kml(kml):
|
||||||
|
|
||||||
|
|
||||||
def render_to_kml(*args, **kwargs):
|
def render_to_kml(*args, **kwargs):
|
||||||
"Renders the response as KML (using the correct MIME type)."
|
"Render the response as KML (using the correct MIME type)."
|
||||||
return HttpResponse(
|
return HttpResponse(
|
||||||
loader.render_to_string(*args, **kwargs),
|
loader.render_to_string(*args, **kwargs),
|
||||||
content_type='application/vnd.google-earth.kml+xml',
|
content_type='application/vnd.google-earth.kml+xml',
|
||||||
|
@ -31,7 +31,7 @@ def render_to_kml(*args, **kwargs):
|
||||||
|
|
||||||
def render_to_kmz(*args, **kwargs):
|
def render_to_kmz(*args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Compresses the KML content and returns as KMZ (using the correct
|
Compress the KML content and return as KMZ (using the correct
|
||||||
MIME type).
|
MIME type).
|
||||||
"""
|
"""
|
||||||
return HttpResponse(
|
return HttpResponse(
|
||||||
|
@ -41,5 +41,5 @@ def render_to_kmz(*args, **kwargs):
|
||||||
|
|
||||||
|
|
||||||
def render_to_text(*args, **kwargs):
|
def render_to_text(*args, **kwargs):
|
||||||
"Renders the response using the MIME type for plain text."
|
"Render the response using the MIME type for plain text."
|
||||||
return HttpResponse(loader.render_to_string(*args, **kwargs), content_type='text/plain')
|
return HttpResponse(loader.render_to_string(*args, **kwargs), content_type='text/plain')
|
||||||
|
|
|
@ -18,9 +18,9 @@ class KMLSitemap(Sitemap):
|
||||||
|
|
||||||
def _build_kml_sources(self, sources):
|
def _build_kml_sources(self, sources):
|
||||||
"""
|
"""
|
||||||
Goes through the given sources and returns a 3-tuple of
|
Go through the given sources and return a 3-tuple of the application
|
||||||
the application label, module name, and field name of every
|
label, module name, and field name of every GeometryField encountered
|
||||||
GeometryField encountered in the sources.
|
in the sources.
|
||||||
|
|
||||||
If no sources are provided, then all models.
|
If no sources are provided, then all models.
|
||||||
"""
|
"""
|
||||||
|
|
|
@ -56,6 +56,6 @@ def kml(request, label, model, field_name=None, compress=False, using=DEFAULT_DB
|
||||||
|
|
||||||
def kmz(request, label, model, field_name=None, using=DEFAULT_DB_ALIAS):
|
def kmz(request, label, model, field_name=None, using=DEFAULT_DB_ALIAS):
|
||||||
"""
|
"""
|
||||||
This view returns KMZ for the given app label, model, and field name.
|
Return KMZ for the given app label, model, and field name.
|
||||||
"""
|
"""
|
||||||
return kml(request, label, model, field_name, compress=True, using=using)
|
return kml(request, label, model, field_name, compress=True, using=using)
|
||||||
|
|
|
@ -150,7 +150,7 @@ class LayerMapping:
|
||||||
|
|
||||||
# #### Checking routines used during initialization ####
|
# #### Checking routines used during initialization ####
|
||||||
def check_fid_range(self, fid_range):
|
def check_fid_range(self, fid_range):
|
||||||
"This checks the `fid_range` keyword."
|
"Check the `fid_range` keyword."
|
||||||
if fid_range:
|
if fid_range:
|
||||||
if isinstance(fid_range, (tuple, list)):
|
if isinstance(fid_range, (tuple, list)):
|
||||||
return slice(*fid_range)
|
return slice(*fid_range)
|
||||||
|
@ -163,9 +163,9 @@ class LayerMapping:
|
||||||
|
|
||||||
def check_layer(self):
|
def check_layer(self):
|
||||||
"""
|
"""
|
||||||
This checks the Layer metadata, and ensures that it is compatible
|
Check the Layer metadata and ensure that it's compatible with the
|
||||||
with the mapping information and model. Unlike previous revisions,
|
mapping information and model. Unlike previous revisions, there is no
|
||||||
there is no need to increment through each feature in the Layer.
|
need to increment through each feature in the Layer.
|
||||||
"""
|
"""
|
||||||
# The geometry field of the model is set here.
|
# The geometry field of the model is set here.
|
||||||
# TODO: Support more than one geometry field / model. However, this
|
# TODO: Support more than one geometry field / model. However, this
|
||||||
|
@ -259,7 +259,7 @@ class LayerMapping:
|
||||||
self.fields[field_name] = fields_val
|
self.fields[field_name] = fields_val
|
||||||
|
|
||||||
def check_srs(self, source_srs):
|
def check_srs(self, source_srs):
|
||||||
"Checks the compatibility of the given spatial reference object."
|
"Check the compatibility of the given spatial reference object."
|
||||||
|
|
||||||
if isinstance(source_srs, SpatialReference):
|
if isinstance(source_srs, SpatialReference):
|
||||||
sr = source_srs
|
sr = source_srs
|
||||||
|
@ -277,7 +277,7 @@ class LayerMapping:
|
||||||
return sr
|
return sr
|
||||||
|
|
||||||
def check_unique(self, unique):
|
def check_unique(self, unique):
|
||||||
"Checks the `unique` keyword parameter -- may be a sequence or string."
|
"Check the `unique` keyword parameter -- may be a sequence or string."
|
||||||
if isinstance(unique, (list, tuple)):
|
if isinstance(unique, (list, tuple)):
|
||||||
# List of fields to determine uniqueness with
|
# List of fields to determine uniqueness with
|
||||||
for attr in unique:
|
for attr in unique:
|
||||||
|
@ -293,8 +293,8 @@ class LayerMapping:
|
||||||
# Keyword argument retrieval routines ####
|
# Keyword argument retrieval routines ####
|
||||||
def feature_kwargs(self, feat):
|
def feature_kwargs(self, feat):
|
||||||
"""
|
"""
|
||||||
Given an OGR Feature, this will return a dictionary of keyword arguments
|
Given an OGR Feature, return a dictionary of keyword arguments for
|
||||||
for constructing the mapped model.
|
constructing the mapped model.
|
||||||
"""
|
"""
|
||||||
# The keyword arguments for model construction.
|
# The keyword arguments for model construction.
|
||||||
kwargs = {}
|
kwargs = {}
|
||||||
|
@ -326,9 +326,9 @@ class LayerMapping:
|
||||||
|
|
||||||
def unique_kwargs(self, kwargs):
|
def unique_kwargs(self, kwargs):
|
||||||
"""
|
"""
|
||||||
Given the feature keyword arguments (from `feature_kwargs`) this routine
|
Given the feature keyword arguments (from `feature_kwargs`), construct
|
||||||
will construct and return the uniqueness keyword arguments -- a subset
|
and return the uniqueness keyword arguments -- a subset of the feature
|
||||||
of the feature kwargs.
|
kwargs.
|
||||||
"""
|
"""
|
||||||
if isinstance(self.unique, str):
|
if isinstance(self.unique, str):
|
||||||
return {self.unique: kwargs[self.unique]}
|
return {self.unique: kwargs[self.unique]}
|
||||||
|
@ -338,9 +338,8 @@ class LayerMapping:
|
||||||
# #### Verification routines used in constructing model keyword arguments. ####
|
# #### Verification routines used in constructing model keyword arguments. ####
|
||||||
def verify_ogr_field(self, ogr_field, model_field):
|
def verify_ogr_field(self, ogr_field, model_field):
|
||||||
"""
|
"""
|
||||||
Verifies if the OGR Field contents are acceptable to the Django
|
Verify if the OGR Field contents are acceptable to the model field. If
|
||||||
model field. If they are, the verified value is returned,
|
they are, return the verified value, otherwise raise an exception.
|
||||||
otherwise the proper exception is raised.
|
|
||||||
"""
|
"""
|
||||||
if (isinstance(ogr_field, OFTString) and
|
if (isinstance(ogr_field, OFTString) and
|
||||||
isinstance(model_field, (models.CharField, models.TextField))):
|
isinstance(model_field, (models.CharField, models.TextField))):
|
||||||
|
@ -397,8 +396,7 @@ class LayerMapping:
|
||||||
def verify_fk(self, feat, rel_model, rel_mapping):
|
def verify_fk(self, feat, rel_model, rel_mapping):
|
||||||
"""
|
"""
|
||||||
Given an OGR Feature, the related model and its dictionary mapping,
|
Given an OGR Feature, the related model and its dictionary mapping,
|
||||||
this routine will retrieve the related model for the ForeignKey
|
retrieve the related model for the ForeignKey mapping.
|
||||||
mapping.
|
|
||||||
"""
|
"""
|
||||||
# TODO: It is expensive to retrieve a model for every record --
|
# TODO: It is expensive to retrieve a model for every record --
|
||||||
# explore if an efficient mechanism exists for caching related
|
# explore if an efficient mechanism exists for caching related
|
||||||
|
@ -420,7 +418,7 @@ class LayerMapping:
|
||||||
|
|
||||||
def verify_geom(self, geom, model_field):
|
def verify_geom(self, geom, model_field):
|
||||||
"""
|
"""
|
||||||
Verifies the geometry -- will construct and return a GeometryCollection
|
Verify the geometry -- construct and return a GeometryCollection
|
||||||
if necessary (for example if the model field is MultiPolygonField while
|
if necessary (for example if the model field is MultiPolygonField while
|
||||||
the mapped shapefile only contains Polygons).
|
the mapped shapefile only contains Polygons).
|
||||||
"""
|
"""
|
||||||
|
@ -447,7 +445,7 @@ class LayerMapping:
|
||||||
|
|
||||||
# #### Other model methods ####
|
# #### Other model methods ####
|
||||||
def coord_transform(self):
|
def coord_transform(self):
|
||||||
"Returns the coordinate transformation object."
|
"Return the coordinate transformation object."
|
||||||
SpatialRefSys = self.spatial_backend.spatial_ref_sys()
|
SpatialRefSys = self.spatial_backend.spatial_ref_sys()
|
||||||
try:
|
try:
|
||||||
# Getting the target spatial reference system
|
# Getting the target spatial reference system
|
||||||
|
@ -461,7 +459,7 @@ class LayerMapping:
|
||||||
) from exc
|
) from exc
|
||||||
|
|
||||||
def geometry_field(self):
|
def geometry_field(self):
|
||||||
"Returns the GeometryField instance associated with the geographic column."
|
"Return the GeometryField instance associated with the geographic column."
|
||||||
# Use `get_field()` on the model's options so that we
|
# Use `get_field()` on the model's options so that we
|
||||||
# get the correct field instance if there's model inheritance.
|
# get the correct field instance if there's model inheritance.
|
||||||
opts = self.model._meta
|
opts = self.model._meta
|
||||||
|
@ -478,7 +476,7 @@ class LayerMapping:
|
||||||
def save(self, verbose=False, fid_range=False, step=False,
|
def save(self, verbose=False, fid_range=False, step=False,
|
||||||
progress=False, silent=False, stream=sys.stdout, strict=False):
|
progress=False, silent=False, stream=sys.stdout, strict=False):
|
||||||
"""
|
"""
|
||||||
Saves the contents from the OGR DataSource Layer into the database
|
Save the contents from the OGR DataSource Layer into the database
|
||||||
according to the mapping dictionary given at initialization.
|
according to the mapping dictionary given at initialization.
|
||||||
|
|
||||||
Keyword Parameters:
|
Keyword Parameters:
|
||||||
|
|
|
@ -10,7 +10,7 @@ from django.contrib.gis.gdal.geometries import GEO_CLASSES
|
||||||
|
|
||||||
def ogrinfo(data_source, num_features=10):
|
def ogrinfo(data_source, num_features=10):
|
||||||
"""
|
"""
|
||||||
Walks the available layers in the supplied `data_source`, displaying
|
Walk the available layers in the supplied `data_source`, displaying
|
||||||
the fields for the first `num_features` features.
|
the fields for the first `num_features` features.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,7 @@ from django.contrib.gis.gdal.field import (
|
||||||
|
|
||||||
def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False):
|
def mapping(data_source, geom_name='geom', layer_key=0, multi_geom=False):
|
||||||
"""
|
"""
|
||||||
Given a DataSource, generates a dictionary that may be used
|
Given a DataSource, generate a dictionary that may be used
|
||||||
for invoking the LayerMapping utility.
|
for invoking the LayerMapping utility.
|
||||||
|
|
||||||
Keyword Arguments:
|
Keyword Arguments:
|
||||||
|
@ -114,7 +114,7 @@ def ogrinspect(*args, **kwargs):
|
||||||
give specific fields to have null, then a list/tuple of OGR field
|
give specific fields to have null, then a list/tuple of OGR field
|
||||||
names may be used.
|
names may be used.
|
||||||
|
|
||||||
Note: This routine calls the _ogrinspect() helper to do the heavy lifting.
|
Note: Call the _ogrinspect() helper to do the heavy lifting.
|
||||||
"""
|
"""
|
||||||
return '\n'.join(s for s in _ogrinspect(*args, **kwargs))
|
return '\n'.join(s for s in _ogrinspect(*args, **kwargs))
|
||||||
|
|
||||||
|
|
|
@ -5,8 +5,8 @@ from django.db import DEFAULT_DB_ALIAS, connections
|
||||||
def add_srs_entry(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None,
|
def add_srs_entry(srs, auth_name='EPSG', auth_srid=None, ref_sys_name=None,
|
||||||
database=None):
|
database=None):
|
||||||
"""
|
"""
|
||||||
This function takes a GDAL SpatialReference system and adds its information
|
Take a GDAL SpatialReference system and add its information to the
|
||||||
to the `spatial_ref_sys` table of the spatial backend. Doing this enables
|
`spatial_ref_sys` table of the spatial backend. Doing this enables
|
||||||
database-level spatial transformations for the backend. Thus, this utility
|
database-level spatial transformations for the backend. Thus, this utility
|
||||||
is useful for adding spatial reference systems not included by default with
|
is useful for adding spatial reference systems not included by default with
|
||||||
the backend:
|
the backend:
|
||||||
|
|
|
@ -17,7 +17,7 @@ register = template.Library()
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def ordinal(value):
|
def ordinal(value):
|
||||||
"""
|
"""
|
||||||
Converts an integer to its ordinal as a string. 1 is '1st', 2 is '2nd',
|
Convert an integer to its ordinal as a string. 1 is '1st', 2 is '2nd',
|
||||||
3 is '3rd', etc. Works for any integer.
|
3 is '3rd', etc. Works for any integer.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -34,7 +34,7 @@ def ordinal(value):
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def intcomma(value, use_l10n=True):
|
def intcomma(value, use_l10n=True):
|
||||||
"""
|
"""
|
||||||
Converts an integer to a string containing commas every three digits.
|
Convert an integer to a string containing commas every three digits.
|
||||||
For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
|
For example, 3000 becomes '3,000' and 45000 becomes '45,000'.
|
||||||
"""
|
"""
|
||||||
if settings.USE_L10N and use_l10n:
|
if settings.USE_L10N and use_l10n:
|
||||||
|
@ -105,7 +105,7 @@ intword_converters = (
|
||||||
@register.filter(is_safe=False)
|
@register.filter(is_safe=False)
|
||||||
def intword(value):
|
def intword(value):
|
||||||
"""
|
"""
|
||||||
Converts a large integer to a friendly text representation. Works best
|
Convert a large integer to a friendly text representation. Works best
|
||||||
for numbers over 1 million. For example, 1000000 becomes '1.0 million',
|
for numbers over 1 million. For example, 1000000 becomes '1.0 million',
|
||||||
1200000 becomes '1.2 million' and '1200000000' becomes '1.2 billion'.
|
1200000 becomes '1.2 million' and '1200000000' becomes '1.2 billion'.
|
||||||
"""
|
"""
|
||||||
|
@ -139,7 +139,7 @@ def intword(value):
|
||||||
@register.filter(is_safe=True)
|
@register.filter(is_safe=True)
|
||||||
def apnumber(value):
|
def apnumber(value):
|
||||||
"""
|
"""
|
||||||
For numbers 1-9, returns the number spelled out. Otherwise, returns the
|
For numbers 1-9, return the number spelled out. Otherwise, return the
|
||||||
number. This follows Associated Press style.
|
number. This follows Associated Press style.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -158,7 +158,7 @@ def apnumber(value):
|
||||||
def naturalday(value, arg=None):
|
def naturalday(value, arg=None):
|
||||||
"""
|
"""
|
||||||
For date values that are tomorrow, today or yesterday compared to
|
For date values that are tomorrow, today or yesterday compared to
|
||||||
present day returns representing string. Otherwise, returns a string
|
present day return representing string. Otherwise, return a string
|
||||||
formatted according to settings.DATE_FORMAT.
|
formatted according to settings.DATE_FORMAT.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
|
@ -186,8 +186,8 @@ def naturalday(value, arg=None):
|
||||||
@register.filter
|
@register.filter
|
||||||
def naturaltime(value):
|
def naturaltime(value):
|
||||||
"""
|
"""
|
||||||
For date and time values shows how many seconds, minutes or hours ago
|
For date and time values show how many seconds, minutes, or hours ago
|
||||||
compared to current timestamp returns representing string.
|
compared to current timestamp return representing string.
|
||||||
"""
|
"""
|
||||||
if not isinstance(value, date): # datetime is a subclass of date
|
if not isinstance(value, date): # datetime is a subclass of date
|
||||||
return value
|
return value
|
||||||
|
|
|
@ -15,7 +15,7 @@ class MessageFailure(Exception):
|
||||||
|
|
||||||
def add_message(request, level, message, extra_tags='', fail_silently=False):
|
def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""
|
||||||
Attempts to add a message to the request using the 'messages' app.
|
Attempt to add a message to the request using the 'messages' app.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
messages = request._messages
|
messages = request._messages
|
||||||
|
@ -36,7 +36,7 @@ def add_message(request, level, message, extra_tags='', fail_silently=False):
|
||||||
|
|
||||||
def get_messages(request):
|
def get_messages(request):
|
||||||
"""
|
"""
|
||||||
Returns the message storage on the request if it exists, otherwise returns
|
Return the message storage on the request if it exists, otherwise return
|
||||||
an empty list.
|
an empty list.
|
||||||
"""
|
"""
|
||||||
return getattr(request, '_messages', [])
|
return getattr(request, '_messages', [])
|
||||||
|
@ -44,10 +44,10 @@ def get_messages(request):
|
||||||
|
|
||||||
def get_level(request):
|
def get_level(request):
|
||||||
"""
|
"""
|
||||||
Returns the minimum level of messages to be recorded.
|
Return the minimum level of messages to be recorded.
|
||||||
|
|
||||||
The default level is the ``MESSAGE_LEVEL`` setting. If this is not found,
|
The default level is the ``MESSAGE_LEVEL`` setting. If this is not found,
|
||||||
the ``INFO`` level is used.
|
use the ``INFO`` level.
|
||||||
"""
|
"""
|
||||||
storage = getattr(request, '_messages', default_storage(request))
|
storage = getattr(request, '_messages', default_storage(request))
|
||||||
return storage.level
|
return storage.level
|
||||||
|
@ -55,11 +55,10 @@ def get_level(request):
|
||||||
|
|
||||||
def set_level(request, level):
|
def set_level(request, level):
|
||||||
"""
|
"""
|
||||||
Sets the minimum level of messages to be recorded, returning ``True`` if
|
Set the minimum level of messages to be recorded, and return ``True`` if
|
||||||
the level was recorded successfully.
|
the level was recorded successfully.
|
||||||
|
|
||||||
If set to ``None``, the default level will be used (see the ``get_level``
|
If set to ``None``, use the default level (see the get_level() function).
|
||||||
method).
|
|
||||||
"""
|
"""
|
||||||
if not hasattr(request, '_messages'):
|
if not hasattr(request, '_messages'):
|
||||||
return False
|
return False
|
||||||
|
@ -68,40 +67,30 @@ def set_level(request, level):
|
||||||
|
|
||||||
|
|
||||||
def debug(request, message, extra_tags='', fail_silently=False):
|
def debug(request, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""Add a message with the ``DEBUG`` level."""
|
||||||
Adds a message with the ``DEBUG`` level.
|
|
||||||
"""
|
|
||||||
add_message(request, constants.DEBUG, message, extra_tags=extra_tags,
|
add_message(request, constants.DEBUG, message, extra_tags=extra_tags,
|
||||||
fail_silently=fail_silently)
|
fail_silently=fail_silently)
|
||||||
|
|
||||||
|
|
||||||
def info(request, message, extra_tags='', fail_silently=False):
|
def info(request, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""Add a message with the ``INFO`` level."""
|
||||||
Adds a message with the ``INFO`` level.
|
|
||||||
"""
|
|
||||||
add_message(request, constants.INFO, message, extra_tags=extra_tags,
|
add_message(request, constants.INFO, message, extra_tags=extra_tags,
|
||||||
fail_silently=fail_silently)
|
fail_silently=fail_silently)
|
||||||
|
|
||||||
|
|
||||||
def success(request, message, extra_tags='', fail_silently=False):
|
def success(request, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""Add a message with the ``SUCCESS`` level."""
|
||||||
Adds a message with the ``SUCCESS`` level.
|
|
||||||
"""
|
|
||||||
add_message(request, constants.SUCCESS, message, extra_tags=extra_tags,
|
add_message(request, constants.SUCCESS, message, extra_tags=extra_tags,
|
||||||
fail_silently=fail_silently)
|
fail_silently=fail_silently)
|
||||||
|
|
||||||
|
|
||||||
def warning(request, message, extra_tags='', fail_silently=False):
|
def warning(request, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""Add a message with the ``WARNING`` level."""
|
||||||
Adds a message with the ``WARNING`` level.
|
|
||||||
"""
|
|
||||||
add_message(request, constants.WARNING, message, extra_tags=extra_tags,
|
add_message(request, constants.WARNING, message, extra_tags=extra_tags,
|
||||||
fail_silently=fail_silently)
|
fail_silently=fail_silently)
|
||||||
|
|
||||||
|
|
||||||
def error(request, message, extra_tags='', fail_silently=False):
|
def error(request, message, extra_tags='', fail_silently=False):
|
||||||
"""
|
"""Add a message with the ``ERROR`` level."""
|
||||||
Adds a message with the ``ERROR`` level.
|
|
||||||
"""
|
|
||||||
add_message(request, constants.ERROR, message, extra_tags=extra_tags,
|
add_message(request, constants.ERROR, message, extra_tags=extra_tags,
|
||||||
fail_silently=fail_silently)
|
fail_silently=fail_silently)
|
||||||
|
|
|
@ -4,7 +4,8 @@ from django.contrib.messages.constants import DEFAULT_LEVELS
|
||||||
|
|
||||||
def messages(request):
|
def messages(request):
|
||||||
"""
|
"""
|
||||||
Returns a lazy 'messages' context variable.
|
Return a lazy 'messages' context variable as well as
|
||||||
|
'DEFAULT_MESSAGE_LEVELS'.
|
||||||
"""
|
"""
|
||||||
return {
|
return {
|
||||||
'messages': get_messages(request),
|
'messages': get_messages(request),
|
||||||
|
|
|
@ -13,10 +13,10 @@ class MessageMiddleware(MiddlewareMixin):
|
||||||
|
|
||||||
def process_response(self, request, response):
|
def process_response(self, request, response):
|
||||||
"""
|
"""
|
||||||
Updates the storage backend (i.e., saves the messages).
|
Update the storage backend (i.e., save the messages).
|
||||||
|
|
||||||
If not all messages could not be stored and ``DEBUG`` is ``True``, a
|
If not all messages could not be stored and ``DEBUG`` is ``True``,
|
||||||
``ValueError`` is raised.
|
raise ValueError.
|
||||||
"""
|
"""
|
||||||
# A higher middleware layer may return a request which does not contain
|
# A higher middleware layer may return a request which does not contain
|
||||||
# messages storage, so make no assumption that it will be there.
|
# messages storage, so make no assumption that it will be there.
|
||||||
|
|
|
@ -7,7 +7,7 @@ LEVEL_TAGS = utils.get_level_tags()
|
||||||
|
|
||||||
class Message:
|
class Message:
|
||||||
"""
|
"""
|
||||||
Represents an actual message that can be stored in any of the supported
|
Represent an actual message that can be stored in any of the supported
|
||||||
storage classes (typically session- or cookie-based) and rendered in a view
|
storage classes (typically session- or cookie-based) and rendered in a view
|
||||||
or template.
|
or template.
|
||||||
"""
|
"""
|
||||||
|
@ -19,7 +19,7 @@ class Message:
|
||||||
|
|
||||||
def _prepare(self):
|
def _prepare(self):
|
||||||
"""
|
"""
|
||||||
Prepares the message for serialization by forcing the ``message``
|
Prepare the message for serialization by forcing the ``message``
|
||||||
and ``extra_tags`` to str in case they are lazy translations.
|
and ``extra_tags`` to str in case they are lazy translations.
|
||||||
|
|
||||||
Known "safe" types (None, int, etc.) are not converted (see Django's
|
Known "safe" types (None, int, etc.) are not converted (see Django's
|
||||||
|
@ -82,7 +82,7 @@ class BaseStorage:
|
||||||
@property
|
@property
|
||||||
def _loaded_messages(self):
|
def _loaded_messages(self):
|
||||||
"""
|
"""
|
||||||
Returns a list of loaded messages, retrieving them first if they have
|
Return a list of loaded messages, retrieving them first if they have
|
||||||
not been loaded yet.
|
not been loaded yet.
|
||||||
"""
|
"""
|
||||||
if not hasattr(self, '_loaded_data'):
|
if not hasattr(self, '_loaded_data'):
|
||||||
|
@ -92,7 +92,7 @@ class BaseStorage:
|
||||||
|
|
||||||
def _get(self, *args, **kwargs):
|
def _get(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Retrieves a list of stored messages. Returns a tuple of the messages
|
Retrieve a list of stored messages. Return a tuple of the messages
|
||||||
and a flag indicating whether or not all the messages originally
|
and a flag indicating whether or not all the messages originally
|
||||||
intended to be stored in this storage were, in fact, stored and
|
intended to be stored in this storage were, in fact, stored and
|
||||||
retrieved; e.g., ``(messages, all_retrieved)``.
|
retrieved; e.g., ``(messages, all_retrieved)``.
|
||||||
|
@ -107,7 +107,7 @@ class BaseStorage:
|
||||||
|
|
||||||
def _store(self, messages, response, *args, **kwargs):
|
def _store(self, messages, response, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Stores a list of messages, returning a list of any messages which could
|
Store a list of messages and return a list of any messages which could
|
||||||
not be stored.
|
not be stored.
|
||||||
|
|
||||||
One type of object must be able to be stored, ``Message``.
|
One type of object must be able to be stored, ``Message``.
|
||||||
|
@ -118,18 +118,17 @@ class BaseStorage:
|
||||||
|
|
||||||
def _prepare_messages(self, messages):
|
def _prepare_messages(self, messages):
|
||||||
"""
|
"""
|
||||||
Prepares a list of messages for storage.
|
Prepare a list of messages for storage.
|
||||||
"""
|
"""
|
||||||
for message in messages:
|
for message in messages:
|
||||||
message._prepare()
|
message._prepare()
|
||||||
|
|
||||||
def update(self, response):
|
def update(self, response):
|
||||||
"""
|
"""
|
||||||
Stores all unread messages.
|
Store all unread messages.
|
||||||
|
|
||||||
If the backend has yet to be iterated, previously stored messages will
|
If the backend has yet to be iterated, store previously stored messages
|
||||||
be stored again. Otherwise, only messages added after the last
|
again. Otherwise, only store messages added after the last iteration.
|
||||||
iteration will be stored.
|
|
||||||
"""
|
"""
|
||||||
self._prepare_messages(self._queued_messages)
|
self._prepare_messages(self._queued_messages)
|
||||||
if self.used:
|
if self.used:
|
||||||
|
@ -140,7 +139,7 @@ class BaseStorage:
|
||||||
|
|
||||||
def add(self, level, message, extra_tags=''):
|
def add(self, level, message, extra_tags=''):
|
||||||
"""
|
"""
|
||||||
Queues a message to be stored.
|
Queue a message to be stored.
|
||||||
|
|
||||||
The message is only queued if it contained something and its level is
|
The message is only queued if it contained something and its level is
|
||||||
not less than the recording level (``self.level``).
|
not less than the recording level (``self.level``).
|
||||||
|
@ -158,7 +157,7 @@ class BaseStorage:
|
||||||
|
|
||||||
def _get_level(self):
|
def _get_level(self):
|
||||||
"""
|
"""
|
||||||
Returns the minimum recorded level.
|
Return the minimum recorded level.
|
||||||
|
|
||||||
The default level is the ``MESSAGE_LEVEL`` setting. If this is
|
The default level is the ``MESSAGE_LEVEL`` setting. If this is
|
||||||
not found, the ``INFO`` level is used.
|
not found, the ``INFO`` level is used.
|
||||||
|
@ -169,7 +168,7 @@ class BaseStorage:
|
||||||
|
|
||||||
def _set_level(self, value=None):
|
def _set_level(self, value=None):
|
||||||
"""
|
"""
|
||||||
Sets a custom minimum recorded level.
|
Set a custom minimum recorded level.
|
||||||
|
|
||||||
If set to ``None``, the default level will be used (see the
|
If set to ``None``, the default level will be used (see the
|
||||||
``_get_level`` method).
|
``_get_level`` method).
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.utils.safestring import SafeData, mark_safe
|
||||||
|
|
||||||
class MessageEncoder(json.JSONEncoder):
|
class MessageEncoder(json.JSONEncoder):
|
||||||
"""
|
"""
|
||||||
Compactly serializes instances of the ``Message`` class as JSON.
|
Compactly serialize instances of the ``Message`` class as JSON.
|
||||||
"""
|
"""
|
||||||
message_key = '__json_message'
|
message_key = '__json_message'
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ class MessageEncoder(json.JSONEncoder):
|
||||||
|
|
||||||
class MessageDecoder(json.JSONDecoder):
|
class MessageDecoder(json.JSONDecoder):
|
||||||
"""
|
"""
|
||||||
Decodes JSON that includes serialized ``Message`` instances.
|
Decode JSON that includes serialized ``Message`` instances.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def process_messages(self, obj):
|
def process_messages(self, obj):
|
||||||
|
@ -51,7 +51,7 @@ class MessageDecoder(json.JSONDecoder):
|
||||||
|
|
||||||
class CookieStorage(BaseStorage):
|
class CookieStorage(BaseStorage):
|
||||||
"""
|
"""
|
||||||
Stores messages in a cookie.
|
Store messages in a cookie.
|
||||||
"""
|
"""
|
||||||
cookie_name = 'messages'
|
cookie_name = 'messages'
|
||||||
# uwsgi's default configuration enforces a maximum size of 4kb for all the
|
# uwsgi's default configuration enforces a maximum size of 4kb for all the
|
||||||
|
@ -62,7 +62,7 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _get(self, *args, **kwargs):
|
def _get(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Retrieves a list of messages from the messages cookie. If the
|
Retrieve a list of messages from the messages cookie. If the
|
||||||
not_finished sentinel value is found at the end of the message list,
|
not_finished sentinel value is found at the end of the message list,
|
||||||
remove it and return a result indicating that not all messages were
|
remove it and return a result indicating that not all messages were
|
||||||
retrieved by this storage.
|
retrieved by this storage.
|
||||||
|
@ -77,8 +77,8 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _update_cookie(self, encoded_data, response):
|
def _update_cookie(self, encoded_data, response):
|
||||||
"""
|
"""
|
||||||
Either sets the cookie with the encoded data if there is any data to
|
Either set the cookie with the encoded data if there is any data to
|
||||||
store, or deletes the cookie.
|
store, or delete the cookie.
|
||||||
"""
|
"""
|
||||||
if encoded_data:
|
if encoded_data:
|
||||||
response.set_cookie(
|
response.set_cookie(
|
||||||
|
@ -92,10 +92,10 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _store(self, messages, response, remove_oldest=True, *args, **kwargs):
|
def _store(self, messages, response, remove_oldest=True, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Stores the messages to a cookie, returning a list of any messages which
|
Store the messages to a cookie and return a list of any messages which
|
||||||
could not be stored.
|
could not be stored.
|
||||||
|
|
||||||
If the encoded data is larger than ``max_cookie_size``, removes
|
If the encoded data is larger than ``max_cookie_size``, remove
|
||||||
messages until the data fits (these are the messages which are
|
messages until the data fits (these are the messages which are
|
||||||
returned), and add the not_finished sentinel value to indicate as much.
|
returned), and add the not_finished sentinel value to indicate as much.
|
||||||
"""
|
"""
|
||||||
|
@ -121,7 +121,7 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _hash(self, value):
|
def _hash(self, value):
|
||||||
"""
|
"""
|
||||||
Creates an HMAC/SHA1 hash based on the value and the project setting's
|
Create an HMAC/SHA1 hash based on the value and the project setting's
|
||||||
SECRET_KEY, modified to make it unique for the present purpose.
|
SECRET_KEY, modified to make it unique for the present purpose.
|
||||||
"""
|
"""
|
||||||
key_salt = 'django.contrib.messages'
|
key_salt = 'django.contrib.messages'
|
||||||
|
@ -129,7 +129,7 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _encode(self, messages, encode_empty=False):
|
def _encode(self, messages, encode_empty=False):
|
||||||
"""
|
"""
|
||||||
Returns an encoded version of the messages list which can be stored as
|
Return an encoded version of the messages list which can be stored as
|
||||||
plain text.
|
plain text.
|
||||||
|
|
||||||
Since the data will be retrieved from the client-side, the encoded data
|
Since the data will be retrieved from the client-side, the encoded data
|
||||||
|
@ -142,10 +142,10 @@ class CookieStorage(BaseStorage):
|
||||||
|
|
||||||
def _decode(self, data):
|
def _decode(self, data):
|
||||||
"""
|
"""
|
||||||
Safely decodes an encoded text stream back into a list of messages.
|
Safely decode an encoded text stream back into a list of messages.
|
||||||
|
|
||||||
If the encoded text stream contained an invalid hash or was in an
|
If the encoded text stream contained an invalid hash or was in an
|
||||||
invalid format, ``None`` is returned.
|
invalid format, return None.
|
||||||
"""
|
"""
|
||||||
if not data:
|
if not data:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -5,7 +5,7 @@ from django.contrib.messages.storage.session import SessionStorage
|
||||||
|
|
||||||
class FallbackStorage(BaseStorage):
|
class FallbackStorage(BaseStorage):
|
||||||
"""
|
"""
|
||||||
Tries to store all messages in the first backend, storing any unstored
|
Try to store all messages in the first backend. Store any unstored
|
||||||
messages in each subsequent backend backend.
|
messages in each subsequent backend backend.
|
||||||
"""
|
"""
|
||||||
storage_classes = (CookieStorage, SessionStorage)
|
storage_classes = (CookieStorage, SessionStorage)
|
||||||
|
@ -18,7 +18,7 @@ class FallbackStorage(BaseStorage):
|
||||||
|
|
||||||
def _get(self, *args, **kwargs):
|
def _get(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Gets a single list of messages from all storage backends.
|
Get a single list of messages from all storage backends.
|
||||||
"""
|
"""
|
||||||
all_messages = []
|
all_messages = []
|
||||||
for storage in self.storages:
|
for storage in self.storages:
|
||||||
|
@ -37,7 +37,7 @@ class FallbackStorage(BaseStorage):
|
||||||
|
|
||||||
def _store(self, messages, response, *args, **kwargs):
|
def _store(self, messages, response, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Stores the messages, returning any unstored messages after trying all
|
Store the messages and return any unstored messages after trying all
|
||||||
backends.
|
backends.
|
||||||
|
|
||||||
For each storage backend, any messages not stored are passed on to the
|
For each storage backend, any messages not stored are passed on to the
|
||||||
|
|
|
@ -9,7 +9,7 @@ from django.contrib.messages.storage.cookie import (
|
||||||
|
|
||||||
class SessionStorage(BaseStorage):
|
class SessionStorage(BaseStorage):
|
||||||
"""
|
"""
|
||||||
Stores messages in the session (that is, django.contrib.sessions).
|
Store messages in the session (that is, django.contrib.sessions).
|
||||||
"""
|
"""
|
||||||
session_key = '_messages'
|
session_key = '_messages'
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class SessionStorage(BaseStorage):
|
||||||
|
|
||||||
def _get(self, *args, **kwargs):
|
def _get(self, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Retrieves a list of messages from the request's session. This storage
|
Retrieve a list of messages from the request's session. This storage
|
||||||
always stores everything it is given, so return True for the
|
always stores everything it is given, so return True for the
|
||||||
all_retrieved flag.
|
all_retrieved flag.
|
||||||
"""
|
"""
|
||||||
|
@ -30,7 +30,7 @@ class SessionStorage(BaseStorage):
|
||||||
|
|
||||||
def _store(self, messages, response, *args, **kwargs):
|
def _store(self, messages, response, *args, **kwargs):
|
||||||
"""
|
"""
|
||||||
Stores a list of messages to the request's session.
|
Store a list of messages to the request's session.
|
||||||
"""
|
"""
|
||||||
if messages:
|
if messages:
|
||||||
self.request.session[self.session_key] = self.serialize_messages(messages)
|
self.request.session[self.session_key] = self.serialize_messages(messages)
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue