Commits

Mikhail Korobov committed ed1bc86

Поддержка ссылок на внешнюю карту

Comments (0)

Files changed (6)

 История изменений
 =================
 
+0.6.1 (2012-04-06)
+==================
+
+* функция ``api.get_external_map_url`` и фильтр ``external_map_url``
+  для получения ссылки на Яндекс Карту, размещенную у Яндекса
+
 0.6 (2012-03-20)
 ================
 * longtitude везде переименованы в longitude;
 
 Библиотека для работы с API Яндекс.Карт. Умеет работать с геокодером и
 формировать адреса статичных карт. Опционально - интеграция с Django:
-кеширование результатов геокодирования, шаблонные фильтры и теги для вывода карт.
+кеширование результатов геокодирования, шаблонные фильтры и теги для вывода
+карт, показ карты для точки из GeoDjango.
+
 Лицензия MIT.
 
-
 Установка
 =========
 
            <!-- Пример с адресом в переменной, указанием уровня детализации и своими атрибутами -->
            {% yandex_map address 200 200 5 "id='my_map'" %}
 
-   и фильтр static_map_url::
+   фильтр static_map_url::
 
            {% load yandex_maps_tags %}
            <img src='{{ "Санкт-Петербург, ул. Бумажная 4"|static_map_url:"300,200,13" }}'>
 
+   фильтр external_map_url::
+
+           {% load yandex_maps_tags %}
+           <a href='{{ address|external_map_url:15 }} '>смотреть карту</a>
+
    В первый раз координаты для вывода карты будут получены через API Яндекс.Карт
    и сохранены в базу. При последующих вызовах координаты для карты будут
    браться из базы. При необходимости можно воспользоваться кешированием в
 from yandex_maps import http
 
 STATIC_MAPS_URL = 'http://static-maps.yandex.ru/1.x/?'
+HOSTED_MAPS_URL = 'http://maps.yandex.ru/?'
 GEOCODE_URL = 'http://geocode-maps.yandex.ru/1.x/?'
 
+def _format_point(longitude, latitude):
+    return '%0.7f,%0.7f' % (float(longitude), float(latitude),)
+
 def get_map_url(api_key, longitude, latitude, zoom, width, height):
     ''' returns URL of static yandex map '''
+    point = _format_point(longitude, latitude)
     params = [
-       'll=%0.7f,%0.7f' % (float(longitude), float(latitude),),
+       'll=%s' % point,
        'size=%d,%d' % (width, height,),
        'z=%d' % zoom,
        'l=map',
-       'pt=%0.7f,%0.7f' % (float(longitude), float(latitude),),
+       'pt=%s' % point,
        'key=%s' % api_key
     ]
     return STATIC_MAPS_URL + '&'.join(params)
 
+
+def get_external_map_url(longitude, latitude, zoom=14):
+    ''' returns URL of hosted yandex map '''
+    point = _format_point(longitude, latitude)
+    params = dict(
+        ll = point,
+        pt = point,
+        l = 'map',
+    )
+    if zoom is not None:
+        params['z'] = zoom
+    return HOSTED_MAPS_URL + urllib.urlencode(params)
+
+
 def geocode(api_key, address, timeout=2):
     ''' returns (longtitude, latitude,) tuple for given address '''
     try:

yandex_maps/models.py

             return ""
         return get_static_map_url(self.longitude, self.latitude, width, height, detail_level)
 
+    def get_external_map_url(self, detail_level=14):
+        return api.get_external_map_url(self.longitude, self.latitude, detail_level)
+
     def fill_geocode_data(self):
         if YANDEX_KEY is not None:
             self.longitude, self.latitude = api.geocode(settings.YANDEX_MAPS_API_KEY, self.address)

yandex_maps/templatetags/yandex_maps_tags.py

 from django.contrib.gis.geos import Point
 from django.utils.html import conditional_escape
 from yandex_maps.models import MapAndAddress, get_static_map_url
+from yandex_maps.api import get_external_map_url
+
 register = template.Library()
 
-def _url_for(address, *args, **kwargs):
+# FIXME: этот код ужасен :)
+
+def _url_for(address, external, *args, **kwargs):
     if isinstance(address, Point):
-        return get_static_map_url(address.x, address.y, *args, **kwargs)
+        if external:
+            return get_external_map_url(address.x, address.y, *args, **kwargs)
+        else:
+            return get_static_map_url(address.x, address.y, *args, **kwargs)
 
     if not isinstance(address, MapAndAddress):
         address, created = MapAndAddress.objects.get_or_create(address=address)
     try:
-        return address.get_map_url(*args, **kwargs)
-    except:
+        if external:
+            return address.get_external_map_url(*args, **kwargs)
+        else:
+            return address.get_map_url(*args, **kwargs)
+    except Exception:
         return ''
 
+
 @register.filter
 def static_map_url(address, params=None):
     '''Фильтр, который возвращает URL картинки с картой.
 
     '''
     data = [] if params is None else params.split(",")
-    return _url_for(address, *data)
+    return _url_for(address, False, *data)
+
+@register.filter
+def external_map_url(address, zoom=None):
+    '''Фильтр, который возвращает URL карты у яндекса.
+    Можно применять к объекту класса MapAndAddress, к строке с адресом
+    или к экземпляру Point из GeoDjango (например, PointField с координатами).
+
+    Принимает 1 необязательный параметр: уровень детализации.
+
+    Пример:
+
+        <a href='{{ address|external_map_url }}' target='_blank'>посмотреть карту</a>
+
+    '''
+    return _url_for(address, True, zoom)
 
 
 @register.simple_tag
         self.assertEqual(_get_coords(UNKNOWN_ADDRESS), (None, None,))
 
 
+# FIXME: тест полагается на порядок параметров в url
 class MapUrlTest(TestCase):
     def test_map_url(self):
         url = get_map_url(TEST_API_KEY, COORDS[0], COORDS[1], 5, 200, 300)