diff options
| author | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-09-25 01:46:12 +0200 | 
|---|---|---|
| committer | Étienne Loks <etienne.loks@peacefrogs.net> | 2012-09-25 01:46:12 +0200 | 
| commit | 4bc82f3f73577118d3cc534eaf749d16321c552a (patch) | |
| tree | 4af66c0ec67ee8bbc17438cff9298772a9b34a0a | |
| parent | fea0b9ecba616b70c40c0a17bfd808cebcd916d8 (diff) | |
| download | Chimère-4bc82f3f73577118d3cc534eaf749d16321c552a.tar.bz2 Chimère-4bc82f3f73577118d3cc534eaf749d16321c552a.zip  | |
Map: manage hover for markers - work on clustering
* add the possibility to add an alternate icon when the category is
  hovered
* management of click *and* hover for cluster layer
* make clustering of marker not mandatory
* manage icon hover in JS: change icon + category label display on top
  of the marker
| -rw-r--r-- | chimere/migrations/0037_auto__add_field_subcategory_hover_icon.py | 255 | ||||
| -rw-r--r-- | chimere/migrations/0038_auto__chg_field_picturefile_width__chg_field_picturefile_height.py (renamed from chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py) | 0 | ||||
| -rw-r--r-- | chimere/models.py | 14 | ||||
| -rw-r--r-- | chimere/static/chimere/css/styles.css | 22 | ||||
| -rw-r--r-- | chimere/static/chimere/img/bottom-arrow.png | bin | 0 -> 199 bytes | |||
| -rw-r--r-- | chimere/static/chimere/js/jquery.chimere.js | 226 | ||||
| -rw-r--r-- | chimere/templates/chimere/blocks/map_params.html | 2 | 
7 files changed, 435 insertions, 84 deletions
diff --git a/chimere/migrations/0037_auto__add_field_subcategory_hover_icon.py b/chimere/migrations/0037_auto__add_field_subcategory_hover_icon.py new file mode 100644 index 0000000..973730f --- /dev/null +++ b/chimere/migrations/0037_auto__add_field_subcategory_hover_icon.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + +    def forwards(self, orm): +        # Adding field 'SubCategory.hover_icon' +        db.add_column('chimere_subcategory', 'hover_icon', +                      self.gf('django.db.models.fields.related.ForeignKey')(blank=True, related_name='subcat_hovered', null=True, to=orm['chimere.Icon']), +                      keep_default=False) + + +    def backwards(self, orm): +        # Deleting field 'SubCategory.hover_icon' +        db.delete_column('chimere_subcategory', 'hover_icon_id') + + +    models = { +        'chimere.area': { +            'Meta': {'ordering': "('order', 'name')", 'object_name': 'Area'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), +            'default_subcategories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False', 'blank': 'True'}), +            'dynamic_categories': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), +            'external_css': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'layers': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'through': "orm['chimere.AreaLayers']", 'to': "orm['chimere.Layer']"}), +            'lower_right_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {}), +            'restrict_to_extent': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'areas'", 'blank': 'True', 'db_table': "'chimere_subcategory_areas'", 'to': "orm['chimere.SubCategory']"}), +            'upper_left_corner': ('django.contrib.gis.db.models.fields.PointField', [], {'default': "'POINT(0 0)'"}), +            'urn': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50', 'blank': 'True'}), +            'welcome_message': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}) +        }, +        'chimere.arealayers': { +            'Meta': {'ordering': "('order',)", 'object_name': 'AreaLayers'}, +            'area': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Area']"}), +            'default': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'layer': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Layer']"}), +            'order': ('django.db.models.fields.IntegerField', [], {}) +        }, +        'chimere.category': { +            'Meta': {'ordering': "['order']", 'object_name': 'Category'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {}) +        }, +        'chimere.color': { +            'Meta': {'ordering': "['order']", 'object_name': 'Color'}, +            'code': ('django.db.models.fields.CharField', [], {'max_length': '6'}), +            'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'order': ('django.db.models.fields.IntegerField', [], {}) +        }, +        'chimere.colortheme': { +            'Meta': {'object_name': 'ColorTheme'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) +        }, +        'chimere.icon': { +            'Meta': {'object_name': 'Icon'}, +            'height': ('django.db.models.fields.IntegerField', [], {}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'image': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'width': ('django.db.models.fields.IntegerField', [], {}) +        }, +        'chimere.importer': { +            'Meta': {'object_name': 'Importer'}, +            'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), +            'default_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'filtr': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'importer_type': ('django.db.models.fields.CharField', [], {'max_length': '4'}), +            'source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'srid': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'state': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'zipped': ('django.db.models.fields.BooleanField', [], {'default': 'False'}) +        }, +        'chimere.layer': { +            'Meta': {'object_name': 'Layer'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'layer_code': ('django.db.models.fields.TextField', [], {'max_length': '300'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) +        }, +        'chimere.marker': { +            'Meta': {'ordering': "('status', 'name')", 'object_name': 'Marker'}, +            'available_date': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}), +            'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), +            'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'point': ('chimere.widgets.PointField', [], {}), +            'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_marker'", 'null': 'True', 'to': "orm['chimere.Marker']"}), +            'route': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'associated_marker'", 'null': 'True', 'to': "orm['chimere.Route']"}), +            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), +            'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), +            'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}) +        }, +        'chimere.multimediaextension': { +            'Meta': {'object_name': 'MultimediaExtension'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'extensions'", 'to': "orm['chimere.MultimediaType']"}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '6'}) +        }, +        'chimere.multimediafile': { +            'Meta': {'object_name': 'MultimediaFile'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'multimedia_files'", 'to': "orm['chimere.Marker']"}), +            'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'multimedia_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.MultimediaType']"}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), +            'url': ('django.db.models.fields.URLField', [], {'max_length': '200'}) +        }, +        'chimere.multimediatype': { +            'Meta': {'object_name': 'MultimediaType'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'iframe': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'media_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'mime_type': ('django.db.models.fields.CharField', [], {'max_length': '50', 'null': 'True', 'blank': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}) +        }, +        'chimere.news': { +            'Meta': {'object_name': 'News'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'content': ('django.db.models.fields.TextField', [], {}), +            'date': ('django.db.models.fields.DateField', [], {'auto_now_add': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'is_front_page': ('django.db.models.fields.NullBooleanField', [], {'null': 'True', 'blank': 'True'}), +            'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}) +        }, +        'chimere.page': { +            'Meta': {'object_name': 'Page'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'content': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'mnemonic': ('django.db.models.fields.CharField', [], {'max_length': '10', 'null': 'True', 'blank': 'True'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '10', 'null': 'True', 'blank': 'True'}), +            'template_path': ('django.db.models.fields.CharField', [], {'max_length': '150', 'null': 'True', 'blank': 'True'}), +            'title': ('django.db.models.fields.CharField', [], {'max_length': '150'}) +        }, +        'chimere.picturefile': { +            'Meta': {'object_name': 'PictureFile'}, +            'height': ('django.db.models.fields.IntegerField', [], {}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'marker': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'pictures'", 'to': "orm['chimere.Marker']"}), +            'miniature': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '1'}), +            'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100'}), +            'thumbnailfile': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'thumbnailfile_height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'thumbnailfile_width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'width': ('django.db.models.fields.IntegerField', [], {}) +        }, +        'chimere.property': { +            'Meta': {'object_name': 'Property'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'marker': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Marker']"}), +            'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.PropertyModel']"}), +            'value': ('django.db.models.fields.TextField', [], {}) +        }, +        'chimere.propertymodel': { +            'Meta': {'ordering': "('order',)", 'object_name': 'PropertyModel'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'mandatory': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {}), +            'subcategories': ('chimere.widgets.SelectMultipleField', [], {'symmetrical': 'False', 'related_name': "'properties'", 'blank': 'True', 'to': "orm['chimere.SubCategory']"}), +            'type': ('django.db.models.fields.CharField', [], {'max_length': '1'}) +        }, +        'chimere.propertymodelchoice': { +            'Meta': {'object_name': 'PropertyModelChoice'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'propertymodel': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'choices'", 'to': "orm['chimere.PropertyModel']"}), +            'value': ('django.db.models.fields.CharField', [], {'max_length': '150'}) +        }, +        'chimere.route': { +            'Meta': {'ordering': "('status', 'name')", 'object_name': 'Route'}, +            'associated_file': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.RouteFile']", 'null': 'True', 'blank': 'True'}), +            'categories': ('chimere.widgets.SelectMultipleField', [], {'to': "orm['chimere.SubCategory']", 'symmetrical': 'False'}), +            'end_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), +            'height': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'import_key': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'import_source': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'import_version': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}), +            'modified_since_import': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'not_for_osm': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'picture': ('django.db.models.fields.files.ImageField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}), +            'ref_item': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'submited_route'", 'null': 'True', 'to': "orm['chimere.Route']"}), +            'route': ('chimere.widgets.RouteField', [], {}), +            'start_date': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}), +            'status': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'submiter_comment': ('django.db.models.fields.TextField', [], {'max_length': '200', 'null': 'True', 'blank': 'True'}), +            'submiter_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}), +            'submiter_name': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), +            'submiter_session_key': ('django.db.models.fields.CharField', [], {'max_length': '40', 'null': 'True', 'blank': 'True'}), +            'width': ('django.db.models.fields.IntegerField', [], {'null': 'True', 'blank': 'True'}) +        }, +        'chimere.routefile': { +            'Meta': {'ordering': "('name',)", 'object_name': 'RouteFile'}, +            'file_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'raw_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100'}), +            'simplified_file': ('django.db.models.fields.files.FileField', [], {'max_length': '100', 'null': 'True', 'blank': 'True'}) +        }, +        'chimere.subcategory': { +            'Meta': {'ordering': "['category', 'order']", 'object_name': 'SubCategory'}, +            'available': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Category']"}), +            'color_theme': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.ColorTheme']", 'null': 'True', 'blank': 'True'}), +            'dated': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), +            'description': ('django.db.models.fields.TextField', [], {'null': 'True', 'blank': 'True'}), +            'hover_icon': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'subcat_hovered'", 'null': 'True', 'to': "orm['chimere.Icon']"}), +            'icon': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['chimere.Icon']"}), +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'item_type': ('django.db.models.fields.CharField', [], {'max_length': '1'}), +            'name': ('django.db.models.fields.CharField', [], {'max_length': '150'}), +            'order': ('django.db.models.fields.IntegerField', [], {'default': '1000'}) +        }, +        'chimere.tinyurl': { +            'Meta': {'object_name': 'TinyUrl'}, +            'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), +            'parameters': ('django.db.models.fields.CharField', [], {'max_length': '500'}) +        } +    } + +    complete_apps = ['chimere'] diff --git a/chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py b/chimere/migrations/0038_auto__chg_field_picturefile_width__chg_field_picturefile_height.py index dac7145..dac7145 100644 --- a/chimere/migrations/0031_auto__chg_field_picturefile_width__chg_field_picturefile_height.py +++ b/chimere/migrations/0038_auto__chg_field_picturefile_width__chg_field_picturefile_height.py diff --git a/chimere/models.py b/chimere/models.py index 20c598e..c11a115 100644 --- a/chimere/models.py +++ b/chimere/models.py @@ -206,6 +206,8 @@ class SubCategory(models.Model):      name = models.CharField(_(u"Name"), max_length=150)      available = models.BooleanField(_(u"Available"))      icon = models.ForeignKey(Icon, verbose_name=_(u"Icon")) +    hover_icon = models.ForeignKey(Icon, verbose_name=_(u"Hover icon"), +                          blank=True, null=True, related_name='subcat_hovered')      color_theme = models.ForeignKey(ColorTheme, verbose_name=_(u"Color theme"),                                      blank=True, null=True)      order = models.IntegerField(_(u"Order"), default=1000) @@ -519,12 +521,18 @@ class Marker(GeographicItem):              items = {'id':self.id, 'name':json.dumps(self.name),                       'geometry':self.point.geojson,                       'icon_path':cat.icon.image, +                     'icon_hover_path':cat.hover_icon.image \ +                                       if cat.hover_icon else '',                       'icon_width':cat.icon.image.width, -                     'icon_height':cat.icon.image.height,} +                     'icon_height':cat.icon.image.height, +                     'category_name':json.dumps(cat.name)}              jsons.append(u'{"type":"Feature", "geometry":%(geometry)s, '\                  u'"properties":{"pk": %(id)d, "name": %(name)s, '\ -                u'"icon_path":"%(icon_path)s", "icon_width":%(icon_width)d, '\ -                u'"icon_height":%(icon_height)d}}' % items) +                u'"icon_path":"%(icon_path)s", '\ +                u'"icon_hover_path":"%(icon_hover_path)s", '\ +                u'"icon_width":%(icon_width)d, '\ +                u'"icon_height":%(icon_height)d, '\ +                u'"category_name":%(category_name)s}}' % items)          return ",".join(jsons)      @property diff --git a/chimere/static/chimere/css/styles.css b/chimere/static/chimere/css/styles.css index f3af02b..630818f 100644 --- a/chimere/static/chimere/css/styles.css +++ b/chimere/static/chimere/css/styles.css @@ -208,7 +208,7 @@ fieldset{  }  #topbar{ -    z-index:0; +    z-index:10;  }  ul.action{ @@ -889,6 +889,26 @@ div.pp_default .pp_expand{   SimplePanZoom  */ +#main_map.olMap{ +  z-index:0; +} + +#marker_hover{ +  display:none; +  position:absolute; +  z-index:5; +  background-image: url('../img/bottom-arrow.png'); +  background-repeat: no-repeat; +  background-position: center bottom; +} + +#marker_hover_content{ +  margin-bottom:6px; +  background-color:#fff; +  border:1px solid #000; +  padding:0.1em 0.5em; +} +  .olControlSimplePanZoom {    top: 10px;    right: 10px; diff --git a/chimere/static/chimere/img/bottom-arrow.png b/chimere/static/chimere/img/bottom-arrow.png Binary files differnew file mode 100644 index 0000000..7393ffe --- /dev/null +++ b/chimere/static/chimere/img/bottom-arrow.png diff --git a/chimere/static/chimere/js/jquery.chimere.js b/chimere/static/chimere/js/jquery.chimere.js index 37f27a4..4c899bb 100644 --- a/chimere/static/chimere/js/jquery.chimere.js +++ b/chimere/static/chimere/js/jquery.chimere.js @@ -91,6 +91,7 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {              units: 'm',              projection: new OpenLayers.Projection('EPSG:4326'),              theme: null, +            enable_clustering: true,              routing: false, // enable routing management              routing_panel_open: function(){                                      $('#chimere_itinerary_panel').dialog('open'); @@ -260,74 +261,91 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {                          settings.layerVectors, {clickout:false, toggle:false}));              } -            var style = new OpenLayers.Style({ -                   graphicTitle: "${name}", -                   externalGraphic: "${icon}", -                   graphicWidth: "${width}", -                   graphicHeight: "${height}", -                   graphicXOffset: "${offsetx}", -                   graphicYOffset: "${offsety}", -                   graphicOpacity: 1, -                   label: "${label}", -                   fontWeight:'bold', -                   fontSize:'1.3em' -               }, { -               context: { -                 name: function(feature) { -                    if(feature.cluster) { -                        feature.attributes.width = settings.cluster_icon.size.w; -                        feature.attributes.height = settings.cluster_icon.size.h; -                        feature.attributes.offsetx = settings.cluster_icon.offset.x; -                        feature.attributes.offsety = settings.cluster_icon.offset.y; -                    } else{ -                        var marker = feature.attributes.marker -                        feature.attributes.width = marker.icon.size.w; -                        feature.attributes.height = marker.icon.size.h; -                        feature.attributes.offsetx = settings.icon_offset.x; -                        feature.attributes.offsety = settings.icon_offset.y; -                    } -                    return feature.attributes.name; -                 }, -                 label: function(feature) { -                    // clustered features count or blank if feature is not a cluster -                    return feature.cluster ? feature.cluster.length : ""; -                 }, -                 icon: function(feature) { -                    if (feature.cluster){ -                        return settings.cluster_icon.url; -                    } else { -                        return STATIC_URL + 'chimere/img/empty.png'; +            if (settings.enable_clustering){ +                var style = new OpenLayers.Style({ +                       graphicTitle: "${name}", +                       externalGraphic: "${icon}", +                       graphicWidth: "${width}", +                       graphicHeight: "${height}", +                       graphicXOffset: "${offsetx}", +                       graphicYOffset: "${offsety}", +                       graphicOpacity: 1, +                       label: "${label}", +                       fontWeight:'bold', +                       fontSize:'1.3em' +                   }, { +                   context: { +                     name: function(feature) { +                        if(feature.cluster) { +                            feature.attributes.width = settings.cluster_icon.size.w; +                            feature.attributes.height = settings.cluster_icon.size.h; +                            feature.attributes.offsetx = settings.cluster_icon.offset.x; +                            feature.attributes.offsety = settings.cluster_icon.offset.y; +                        } else{ +                            var marker = feature.attributes.marker +                            feature.attributes.width = marker.icon.size.w; +                            feature.attributes.height = marker.icon.size.h; +                            feature.attributes.offsetx = settings.icon_offset.x; +                            feature.attributes.offsety = settings.icon_offset.y; +                        } +                        return feature.attributes.name; +                     }, +                     label: function(feature) { +                        // clustered features count or blank if feature is not a cluster +                        return feature.cluster ? feature.cluster.length : ""; +                     }, +                     icon: function(feature) { +                        if (feature.cluster){ +                            return settings.cluster_icon.url; +                        } else { +                            return STATIC_URL + 'chimere/img/empty.png'; +                        } +                     }, +                     width: function(feature) { return feature.attributes.width; }, +                     height: function(feature) { return feature.attributes.height; }, +                     offsetx: function(feature) { return feature.attributes.offsetx; }, +                     offsety: function(feature) { return feature.attributes.offsety; } +                     }}); + + +                /* Cluster layer */ +                var strategy = new OpenLayers.Strategy.Cluster({distance: 20, +                                                                threshold: 3}); +                settings.layerCluster = new OpenLayers.Layer.Vector("Cluster layer", +                    {styleMap: new OpenLayers.StyleMap({'default': style}), +                     strategies: [strategy]}); +                settings.map.addLayer(settings.layerCluster); + +                var highlightCtrl = new OpenLayers.Control.SelectFeature( +                                                settings.layerCluster, { +                    hover: true, +                    highlightOnly: true, +                    eventListeners: { +                        featurehighlighted:  function(e) { +                        e.feature.attributes.marker.events.triggerEvent('mouseover'); +                        }, +                        featureunhighlighted:  function(e) { +                        e.feature.attributes.marker.events.triggerEvent('mouseout'); +                        }                      } -                 }, -                 width: function(feature) { return feature.attributes.width; }, -                 height: function(feature) { return feature.attributes.height; }, -                 offsetx: function(feature) { return feature.attributes.offsetx; }, -                 offsety: function(feature) { return feature.attributes.offsety; } -                 }}); +                }); +                var selectCtrl = new OpenLayers.Control.SelectFeature( +                                    settings.layerCluster,{ +                                        onSelect: methods.zoomOnCluster +                                    }); -            /* Cluster layer */ -            var strategy = new OpenLayers.Strategy.Cluster({distance: 20, -                                                            threshold: 3}); -            settings.layerCluster = new OpenLayers.Layer.Vector("Cluster layer", -                {styleMap: new OpenLayers.StyleMap({'default': style}), -                 strategies: [strategy]}); -            settings.map.addLayer(settings.layerCluster); +                settings.map.addControl(highlightCtrl); +                settings.map.addControl(selectCtrl); -            var clusterSelect = new OpenLayers.Control.SelectFeature( -                                                settings.layerCluster); -            settings.map.addControl(clusterSelect); -            clusterSelect.activate(); -            settings.layerCluster.events.on({ -                'featureselected': methods.zoomOnCluster, -                'featurehighlighted': function (evt) { -                document.body.style.cursor='pointer';} -            }); +                highlightCtrl.activate(); +                selectCtrl.activate(); + +            }              /* Markers layer */              settings.layerMarkers = new OpenLayers.Layer.Markers('POIs');              settings.map.addLayer(settings.layerMarkers); -            settings.layerMarkers.setOpacity(0.8);              if (settings.dynamic_categories){                  settings.map.events.register('moveend', settings.map, @@ -353,8 +371,10 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {              }              if (!settings.edition){ -                settings.map.events.register('zoomend', null, +                if (settings.enable_clustering){ +                    settings.map.events.register('zoomend', null,                                                methods.cleanCluster); +                }                  methods.loadCategories();                  methods.loadGeoObjects();                  methods.activateContextMenu() @@ -443,13 +463,15 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {          setCurrentPosition: function(lonlat){              settings.current_position = lonlat;          }, -        zoomOnCluster: function(e){ -            if(!e.feature.cluster) // if not cluster +        zoomOnCluster: function(feature){ +            if(!feature.cluster) // if not cluster              { -                e.feature.attributes.marker.events.triggerEvent('click'); +                feature.attributes.marker.events.triggerEvent('click'); +                feature.attributes.marker.events.triggerEvent('mouseover'); +                feature.attributes.marker.events.triggerEvent('mouseout');              } else {                  settings.map.setCenter( -                            e.feature.geometry.getBounds().getCenterLonLat()); +                            feature.geometry.getBounds().getCenterLonLat());                  methods.zoomIn();              }          }, @@ -487,7 +509,9 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {                      success: function (data) {                          settings.layerMarkers.clearMarkers();                          settings.layerVectors.removeAllFeatures(); -                        settings.cluster_array = []; +                        if (settings.enable_clustering){ +                            settings.cluster_array = []; +                        }                          for (var i = 0; i < data.features.length; i++) {                              var feature = data.features[i];                              if (feature.geometry.type == 'Point'){ @@ -496,9 +520,11 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {                                  methods.addRoute(feature);                              }                          } -                        settings.layerCluster.addFeatures( +                        if (settings.enable_clustering){ +                            settings.layerCluster.addFeatures(                                                          settings.cluster_array); -                        methods.cleanCluster(); +                            methods.cleanCluster(); +                        }                      },                      error: function (data) {                          settings.layerMarkers.clearMarkers(); @@ -655,8 +681,13 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {              var lon = mark.geometry.coordinates[0];              var size = new OpenLayers.Size(mark.properties.icon_width,                                             mark.properties.icon_height); -            var iconclone = new OpenLayers.Icon(MEDIA_URL + mark.properties.icon_path, -                                            size, settings.icon_offset); +            var icon_url = MEDIA_URL + mark.properties.icon_path; +            var icon_hover_url = ''; +            if (mark.properties.icon_hover_path){ +                var icon_hover_url = MEDIA_URL + mark.properties.icon_hover_path; +            } +            var iconclone = new OpenLayers.Icon(icon_url, size, +                                                settings.icon_offset);              var feature = new OpenLayers.Feature(settings.layerMarkers,                        new OpenLayers.LonLat(lon, lat).transform( @@ -671,6 +702,9 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {              feature.data.overflow = 'hidden';              var marker = feature.createMarker();              marker.pk = feature.pk; +            marker.icon_url = icon_url; +            marker.icon_hover_url = icon_hover_url; +            marker.category_name = mark.properties.category_name;              /* manage markers events */              var _popup = function() {                  /* show the popup */ @@ -734,10 +768,45 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {              };              var markerOver = function (evt) {                  document.body.style.cursor='pointer'; +                var marker = evt.object; +                if (marker.icon_hover_url){ +                    marker.setUrl(marker.icon_hover_url); +                } +                px = settings.map.getPixelFromLonLat(marker.lonlat); +                marker_hover = $('#marker_hover'); +                marker_hover_content = $('#marker_hover_content'); +                marker_hover_content.html(marker.category_name); +                var map_position = $(settings.map.div).offset(); + +                var width = marker_hover.width(); +                width += parseInt(marker_hover.css("padding-left"), 10) +                       + parseInt(marker_hover.css("padding-right"), 10) +                       + parseInt(marker_hover.css("margin-left"), 10) +                       + parseInt(marker_hover.css("margin-right"), 10) +                       + parseInt(marker_hover.css("borderLeftWidth"), 10) +                       + parseInt(marker_hover.css("borderRightWidth"), 10); +                $('#marker_hover').css('left', px.x + map_position.left +                                       - width/2 + 1); +                var height = marker_hover.height(); +                height += parseInt(marker_hover.css("padding-top"), 10) +                       + parseInt(marker_hover.css("padding-bottom"), 10) +                       + parseInt(marker_hover.css("margin-top"), 10) +                       + parseInt(marker_hover.css("margin-bottom"), 10) +                       + parseInt(marker_hover.css("borderBottomWidth"), 10) +                       + parseInt(marker_hover.css("borderTopWidth"), 10); +                $('#marker_hover').css('top', px.y + map_position.top +                                       - height +                                       - marker.icon.size.h); +                $('#marker_hover').show();                  OpenLayers.Event.stop(evt);              };              var markerOut = function (evt) {                  document.body.style.cursor='auto'; +                var marker = evt.object; +                if (marker.icon_hover_url){ +                    marker.setUrl(marker.icon_url); +                } +                $('#marker_hover').hide();                  OpenLayers.Event.stop(evt);              };              marker.events.register('click', feature, markerClick); @@ -753,18 +822,17 @@ OpenLayers.Layer.MapQuestOSM = OpenLayers.Class(OpenLayers.Layer.XYZ, {                  methods.loadCategories();              } - +            if (settings.enable_clustering){              // manage cluster layer -            var point = new OpenLayers.Geometry.Point(lon, lat).transform( +                var point = new OpenLayers.Geometry.Point(lon, lat).transform(                                                          EPSG_DISPLAY_PROJECTION,                                                          EPSG_PROJECTION); -            var feat = new OpenLayers.Feature.Vector(point); -            feat.attributes = { icon: MEDIA_URL + mark.properties.icon_path, -                                name: "", label:"", pk:mark.properties.pk, -                                marker:marker}; -            settings.cluster_array.push(feat); - - +                var feat = new OpenLayers.Feature.Vector(point); +                feat.attributes = { icon: MEDIA_URL + mark.properties.icon_path, +                                    name: "", label:"", pk:mark.properties.pk, +                                    marker:marker}; +                settings.cluster_array.push(feat); +            }              return feature;          }, diff --git a/chimere/templates/chimere/blocks/map_params.html b/chimere/templates/chimere/blocks/map_params.html index 2247c06..7608180 100644 --- a/chimere/templates/chimere/blocks/map_params.html +++ b/chimere/templates/chimere/blocks/map_params.html @@ -40,4 +40,4 @@      $('#maps').chimere('zoom', {'area':{{zoom}} });      {% endif %}  </script> - +<div id='marker_hover'><div id='marker_hover_content'></div></div>  | 
