diff options
author | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-02-21 17:13:43 +0100 |
---|---|---|
committer | Étienne Loks <etienne.loks@iggdrasil.net> | 2016-02-21 17:13:43 +0100 |
commit | fee4daab6598a3d6e51a31e2e70e059fc5419908 (patch) | |
tree | abd3460120b64a054600cfbd04cf4ae18ee6ce30 /chimere/models.py | |
parent | c3f043e4937bd9ed7c68a38488e588866943f4c5 (diff) | |
download | Chimère-fee4daab6598a3d6e51a31e2e70e059fc5419908.tar.bz2 Chimère-fee4daab6598a3d6e51a31e2e70e059fc5419908.zip |
Basic integration of polygons
Diffstat (limited to 'chimere/models.py')
-rw-r--r-- | chimere/models.py | 266 |
1 files changed, 138 insertions, 128 deletions
diff --git a/chimere/models.py b/chimere/models.py index 94da386..cae9503 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -# Copyright (C) 2008-2015 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> +# Copyright (C) 2008-2016 Étienne Loks <etienne.loks_AT_peacefrogsDOTnet> # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as @@ -44,7 +44,7 @@ from django.template import defaultfilters from django.utils.translation import ugettext_lazy as _ from chimere.widgets import HiddenPointChooserWidget, PointField, RouteField, \ - SelectMultipleField, TextareaWidget, DatePickerWidget + SelectMultipleField, TextareaWidget, DatePickerWidget, PolygonField from chimere.utils import KMLManager, OSMManager, ShapefileManager, \ GeoRSSManager, CSVManager, HtmlXsltManager, XMLXsltManager, JsonManager @@ -244,6 +244,7 @@ class SubCategory(models.Model): default=True) TYPE = (('M', _(u'Marker')), ('R', _(u'Route')), + ('P', _(u'Polygon')), ('B', _(u'Both')),) item_type = models.CharField(_(u"Item type"), max_length=1, choices=TYPE) dated = models.BooleanField(_(u"Is dated"), default=False) @@ -520,6 +521,94 @@ class GeographicItem(models.Model): class Meta: abstract = True + def __unicode__(self): + return self.name + + def __init__(self, *args, **kwargs): + super(GeographicItem, self).__init__(*args, **kwargs) + # add read attributes for properties + for pm in self.all_properties(): + attr_name = pm.getAttrName() + if not hasattr(self, attr_name): + val = '' + property = self.getProperty(pm) + if property: + val = property.python_value + setattr(self, attr_name, val) + if not hasattr(self, attr_name + '_set'): + setattr(self, attr_name + '_set', + property_setter(self.__class__, pm)) + + @property + def geometry(self): + return getattr(self, self.geom_attr).wkt + + def getProperty(self, propertymodel, safe=None): + """Get the property of an associated property model. + If safe set to True, verify if the property is available + """ + if safe and not propertymodel.available: + return + try: + property = Property.objects.get(propertymodel=propertymodel, + marker=self) + except Property.DoesNotExist: + return + return property + + def getProperties(self): + """Get all the property availables + """ + properties = [] + for pm in PropertyModel.objects.filter(available=True): + property = self.getProperty(pm) + if property: + properties.append(property) + return properties + + def setProperty(self, pm, value): + u""" + Set a property + """ + properties = Property.objects.filter(marker=self, + propertymodel=pm).all() + # in case of multiple edition as the same time delete arbitrary + # the others + if len(properties) > 1: + for property in properties[1:]: + property.delete() + if pm.type == 'C' and value: + try: + value = str(int(value)) + except ValueError: + choice = PropertyModelChoice.objects.filter(propertymodel=pm, + value=value) + if choice.count(): + value = choice.all()[0].pk + else: + choice = PropertyModelChoice.objects.create( + value=value, propertymodel=pm) + value = choice.pk + # new property + if not properties: + new_property = Property.objects.create( + marker=self, propertymodel=pm, value=value) + new_property.save() + else: + property = properties[0] + property.value = value + property.save() + + def saveProperties(self, values): + """ + Save properties + """ + for propertymodel in PropertyModel.objects.filter(available=True): + val = u"" + if unicode(propertymodel.id) in values: + val = values[unicode(propertymodel.id)] + self.setProperty(propertymodel, val) + def get_key(self, key): key_vals = self.import_key.split(';') for k_v in key_vals: @@ -592,23 +681,9 @@ class Marker(GeographicItem): null=True) objects = models.GeoManager() - def __unicode__(self): - return self.name - - def __init__(self, *args, **kwargs): - super(Marker, self).__init__(*args, **kwargs) - # add read attributes for properties - for pm in self.all_properties(): - attr_name = pm.getAttrName() - if not hasattr(self, attr_name): - val = '' - property = self.getProperty(pm) - if property: - val = property.python_value - setattr(self, attr_name, val) - if not hasattr(self, attr_name + '_set'): - setattr(self, attr_name + '_set', - property_setter(self.__class__, pm)) + class Meta: + ordering = ('status', 'name') + verbose_name = _(u"Point of interest") def get_init_multi(self): multis = [forms.model_to_dict(multi) @@ -649,17 +724,9 @@ class Marker(GeographicItem): return shortify(self.description) @property - def geometry(self): - return self.point.wkt - - @property def geom_attr(self): return 'point' - class Meta: - ordering = ('status', 'name') - verbose_name = _(u"Point of interest") - def getLatitude(self): '''Return the latitude ''' @@ -670,72 +737,6 @@ class Marker(GeographicItem): ''' return self.point.x - def getProperty(self, propertymodel, safe=None): - """Get the property of an associated property model. - If safe set to True, verify if the property is available - """ - if safe and not propertymodel.available: - return - try: - property = Property.objects.get(propertymodel=propertymodel, - marker=self) - except Property.DoesNotExist: - return - return property - - def getProperties(self): - """Get all the property availables - """ - properties = [] - for pm in PropertyModel.objects.filter(available=True): - property = self.getProperty(pm) - if property: - properties.append(property) - return properties - - def setProperty(self, pm, value): - u""" - Set a property - """ - properties = Property.objects.filter(marker=self, - propertymodel=pm).all() - # in case of multiple edition as the same time delete arbitrary - # the others - if len(properties) > 1: - for property in properties[1:]: - property.delete() - if pm.type == 'C' and value: - try: - value = str(int(value)) - except ValueError: - choice = PropertyModelChoice.objects.filter(propertymodel=pm, - value=value) - if choice.count(): - value = choice.all()[0].pk - else: - choice = PropertyModelChoice.objects.create( - value=value, propertymodel=pm) - value = choice.pk - # new property - if not properties: - new_property = Property.objects.create( - marker=self, propertymodel=pm, value=value) - new_property.save() - else: - property = properties[0] - property.value = value - property.save() - - def saveProperties(self, values): - """ - Save properties - """ - for propertymodel in PropertyModel.objects.filter(available=True): - val = u"" - if unicode(propertymodel.id) in values: - val = values[unicode(propertymodel.id)] - self.setProperty(propertymodel, val) - def getGeoJSON(self, categories_id=[]): '''Return a GeoJSON string ''' @@ -1175,9 +1176,6 @@ class Route(GeographicItem): default=True) objects = models.GeoManager() - def __unicode__(self): - return self.name - class Meta: ordering = ('status', 'name') verbose_name = _(u"Route") @@ -1205,10 +1203,6 @@ class Route(GeographicItem): property_setter(self.__class__, pm)) @property - def geometry(self): - return self.route.wkt - - @property def geom_attr(self): return 'route' @@ -1228,29 +1222,6 @@ class Route(GeographicItem): for pict in self.associated_marker.all()[0].pictures.all()] return picts - def getProperty(self, propertymodel, safe=None): - """Get the property of an associated property model. - If safe set to True, verify if the property is available - """ - if safe and not propertymodel.available: - return - try: - property = Property.objects.get(propertymodel=propertymodel, - marker=self) - except Property.DoesNotExist: - return - return property - - def getProperties(self): - """Get all the property availables - """ - properties = [] - for pm in PropertyModel.objects.filter(available=True): - property = self.getProperty(pm) - if property: - properties.append(property) - return properties - def getGeoJSON(self, color="#000"): '''Return a GeoJSON string ''' @@ -1262,11 +1233,6 @@ class Route(GeographicItem): "color": color}} return json.dumps(attributes) - def getTinyUrl(self): - parameters = 'current_feature=%d&checked_categories=%s' % ( - self.id, self.categories[0].id) - return TinyUrl.getUrnByParameters(parameters) - pre_save_route_values = {} @@ -1370,6 +1336,44 @@ class AggregatedRoute(models.Model): return json.dumps(attributes) +class Polygon(GeographicItem): + '''Polygon on the map + ''' + ref_item = models.ForeignKey( + "Polygon", blank=True, null=True, verbose_name=_(u"Reference polygon"), + related_name='submited_polygon') + polygon = PolygonField( + _(u"Polygon"), srid=settings.CHIMERE_EPSG_DISPLAY_PROJECTION) + picture = models.ImageField( + _(u"Image"), upload_to='upload', blank=True, null=True, + height_field='height', width_field='width') + height = models.IntegerField(_(u"Height"), blank=True, null=True) + width = models.IntegerField(_(u"Width"), blank=True, null=True) + objects = models.GeoManager() + + class Meta: + ordering = ('status', 'name') + verbose_name = _(u"Polygon") + + @property + def geom_attr(self): + return 'polygon' + + def getGeoJSON(self, color="#000", inner_color='#0F0'): + '''Return a GeoJSON string + ''' + if '#' not in color: + color = '#' + color + if '#' not in inner_color: + color = '#' + inner_color + attributes = {"type": "Feature", + "geometry": json.loads(self.route.geojson), + "properties": {"pk": self.id, "name": self.name, + "color": color, + "inner_color": inner_color}} + return json.dumps(attributes) + + class SimplePoint: """ Point in the map (not in the database) @@ -1549,6 +1553,12 @@ class Area(models.Model, SimpleArea): """ return Q(route__contained=self.getWkt()) + def getIncludePolygon(self): + """ + Get the sql statement for the test if the route is included in the area + """ + return Q(polygon__contained=self.getWkt()) + pre_save_area_values = {} |