проблема с загрузкой большого количества маркеров в openlaye

Mapserver, GeoServer, MapGuide, Google и другое ПО для веб-картографии
Ответить
Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

проблема с загрузкой большого количества маркеров в openlaye

Сообщение Андрей Щ » 21 май 2013, 12:28

Всем привет! создал карту на openlayers. На эту карту помещаю маркеры..координаты маркеров берутся из моей базы данных (sqlserver 2008), проблема в том,что количество маркеров около 1500. Карта отображается нормально. Но маркеры не проставляются..вернее браузер открывается , карта рисуется, и в этот момент начинаются жуткие тормоза. т.к. на карту наносятся большое количество маркеров. Как обойти эти тормоза с минимальным изменением кода(если конечно реально). Может сделать какое-нибудь кэширование ? Приложение mvc-ое. Попытаюсь скинуть весь код.(на клиенте.)

Код: Выделить всё

   var map;
    var markers;
    var marker_gmap = [];

    function ejecutar() {
        init(3);
        //loadMarkers();
    }
    function init(b,kor_1,kor_2) {
        if (b == 3) {


            map = new OpenLayers.Map("basicMap", {
                controls: [
                    new OpenLayers.Control.Navigation(),
                    new OpenLayers.Control.PanZoomBar(),
                    new OpenLayers.Control.LayerSwitcher(),
                    new OpenLayers.Control.Attribution()],
                maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
                maxResolution: 156543.0399,
                numZoomLevels: 2,
                units: 'm',
                projection: new OpenLayers.Projection("EPSG:900913"),
                displayProjection: new OpenLayers.Projection("EPSG:4326")
            });
        }
            // Define the map layer
            // Here we use a predefined layer that will be kept up to date with URL changes
            layerMapnik = new OpenLayers.Layer.OSM.Mapnik("MapaCiudad");
            map.addLayer(layerMapnik);
            var lonLat = new OpenLayers.LonLat(50.5206298828125, 55.15881723298661).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
            //map.setCenter(new OpenLayers.LonLat(-3.862788677215576, 43.4669443349282) // Center of the map
            map.zoomTo(9);
            map.setCenter(lonLat, 19);

        }
        //создаем дорогу
        var lineLayer = new OpenLayers.Layer.Vector("Линии"); 
        map.addLayer(lineLayer);                    
        map.addControl(new OpenLayers.Control.DrawFeature(lineLayer, OpenLayers.Handler.Path));
    
        var points = new Array(
         
           new OpenLayers.Geometry.Point(50.05783, 55.299518),
           new OpenLayers.Geometry.Point(50.062724, 55.290132),
           new OpenLayers.Geometry.Point(50.083282, 55.273152),
           new OpenLayers.Geometry.Point(50.238518, 55.201065),
           new OpenLayers.Geometry.Point(50.261606, 55.195401),


           new OpenLayers.Geometry.Point(50.304834, 55.184708)
          


        );


        var line = new OpenLayers.Geometry.LineString(points);
        line.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));

        var style = { 
            strokeColor: '#0000ff', 
            strokeOpacity: 0.5,
            strokeWidth: 5
        };

        var lineFeature = new OpenLayers.Feature.Vector(line, null, style);
        lineLayer.addFeatures([lineFeature]);
    
    

        //создаем маркер
        markers = new OpenLayers.Layer.Markers("Marcadores");
        map.addLayer(markers);

        if (b == 2) 
        {           
                
                ////=================  =========стили для маркеров и тут хранятся координаты
                var size = new OpenLayers.Size(30, 30);
                var offset = new OpenLayers.Pixel(-(size.w / 2), -size.h);
                
                var location = new OpenLayers.LonLat(kor_1, kor_2).transform(new OpenLayers.Projection("EPSG:4326"), map.getProjectionObject());
                var icon = new OpenLayers.Icon('../Content/themes/base/images/pen.png', size, offset);
                markers.addMarker(new OpenLayers.Marker(location, icon.clone()));

                markers.events.register("click", markers, function(e){
                    popup = new OpenLayers.Popup.FramedCloud("chicken",
                    new OpenLayers.LonLat(kor_1,kor_2),
                    new OpenLayers.Size(200, 200),
                    "I was here <br><img src='uploads/me.png' width='90' height='90'>",
                    null, true);
                    map.addPopup(popup);
                });

        }
</script>
</head>
<body onload="ejecutar();">
    <script type="text/javascript">        
       
        function add_metka() {
            function dobavit(koor1, koor2) {

                init(2, koor1, koor2);                
            }
            function mess() {
                alert('ok');
            }
 // вот сдесь чтение координат циклом из базы данных
                @foreach (Дорожное_строительство.Models.koordinats_piket picket  in ViewBag.Data)
            {
            <text>
                dobavit(@picket.Dolgota, @picket.Shirota);
               
            </text> 
             }
        }

        setTimeout('add_metka()', 6000)
    </script>
<div id="basicMap" ></div>   
на сервере(на контроллере):

Код: Выделить всё

public class KartaController : Controller
    {
        DataClasses1DataContext db = new DataClasses1DataContext();//подсоединяем нашу бд.
       
    
       

        public ActionResult Index()
        {
            List<koordinats_piket> info = new List<koordinats_piket>();

            var result = db.Координаты_пикетов.Select(all => all);

            foreach (var a in result)
            {
                for (int i = 0; i <= 10; i++)
                {
                    // перевод из формата ddmmss в dddddd
                    string[] parts = a.Долгота.Split(' ');
                    double Dolgota = 0;
                    if (parts.Count() > 0)
                        Dolgota += double.Parse(parts[0].Replace('.', ','));
                    if (parts.Count() > 1)
                        Dolgota += double.Parse(parts[1].Replace('.', ',')) / 60d;
                    if (parts.Count() > 2)
                        Dolgota += double.Parse(parts[2].Replace('.', ',')) / 3600d;
                    string[] parts2 = a.Широта.Split(' ');

                    double Shirota = 0;
                    if (parts2.Count() > 0)
                        Shirota += double.Parse(parts2[0].Replace('.', ','));
                    if (parts2.Count() > 1)
                        Shirota += double.Parse(parts2[1].Replace('.', ',')) / 60d;
                    if (parts2.Count() > 2)
                        Shirota += double.Parse(parts2[2].Replace('.', ',')) / 3600d;

                    info.Add(new koordinats_piket
                    {
                        Shirota = Shirota.ToString().Replace(',', '.'),
                        Dolgota = Dolgota.ToString().Replace(',', '.')
                    });
                    ViewBag.Data = info;
                }
               
            }

            return View("Index");
        }

Аватара пользователя
novia
Гуру
Сообщения: 2261
Зарегистрирован: 29 апр 2011, 15:06
Репутация: 489
Откуда: Тель-Авив

Re: проблема с загрузкой большого количества маркеров в open

Сообщение novia » 21 май 2013, 12:39

зачем вам 1500 маркеров на карте? используйте кластеризацию
понравилось? жми палец вверх :!:

Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Андрей Щ » 21 май 2013, 12:45

вот такое у меня задание) а как ее сделать вернее внедрить в мой код кластеризацию?подскажите пожалуйста.

cibo
Интересующийся
Сообщения: 36
Зарегистрирован: 23 июл 2012, 13:51
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение cibo » 21 май 2013, 20:55

1500 маркеров это даже не колтчество. Вывожу 100 000 точек на слой тормозов даже не наблюдаю. Правда postgres у меня. Дело в скорее всего в БД . Посмотрите как долго запрос с сервера возвращается.

Аватара пользователя
novia
Гуру
Сообщения: 2261
Зарегистрирован: 29 апр 2011, 15:06
Репутация: 489
Откуда: Тель-Авив

Re: проблема с загрузкой большого количества маркеров в open

Сообщение novia » 21 май 2013, 21:05

дело не в тормозах, а в целесообразности одновременного размещения такого количества маркеров на интерактивной карте
понравилось? жми палец вверх :!:

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Denis Rykov » 21 май 2013, 22:15

1) Я вам уже писал - не используйте маркеры, используйте векторные фичи и нужный стиль;
2) Для отображения большого количества векторных используйте кластеризацию, на сайте OpenLayers есть пример.

В Leaflet (конкурент OpenLayers) кластеризация из коробки выглядит довольно неплохо, что-то подобное есть и для OpenLayers в виде отдельного расширения - поищите, но если вам не нужны красивости, то можно остановиться на нативных возможностях OpenLayers.

UPD.: Вот нашел пример и вот описание.
Spatial is now, more than ever, just another column- The Geometry Column.

Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Андрей Щ » 23 май 2013, 14:29

Пытаюсь создать вектор(маркер)..что дальше делать?..этого кода явно недостаточно чтоб добавить маркер на карту..может кто подскажет..что делать дальше..?какой код далее?

Код: Выделить всё

var vectorLayer = new OpenLayers.Layer.Vector("Overlay");
        map.addLayer(vectorLayer);

Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Андрей Щ » 23 май 2013, 14:30

дальше это ?

Код: Выделить всё

var feature = new OpenLayers.Feature.Vector(
            new OpenLayers.Geometry.Point(104, 52).transform(
                        new OpenLayers.Projection("EPSG:4326"), // преобразование из WGS 1984
                        new OpenLayers.Projection("EPSG:900913")) // в Spherical Mercator Projection
                      ,
            {some:'data'},
            {externalGraphic: 'http://icons.iconarchive.com/icons/icons-land/vista-map-markers/256/Map-Marker-Ball-Pink-icon.png', graphicHeight: 50, graphicWidth: 50, rotation: 90});
            vectorLayer.addFeatures([feature]);

            map.addLayer(vectorLayer);

Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Андрей Щ » 23 май 2013, 18:11

сделал вектор..наконец-то....но не могу применить кластеризацию..видать ошибка в коде...может кто скажет где ошибка?и как привязать popup, для каждого вектора вернее содержание (контент)чтоб был разным а не одинаковым у каждого вектора?

Код: Выделить всё

var vectorLayer = new OpenLayers.Layer.Vector("Overlay", {
            
            strategies: [
                new OpenLayers.Strategy.Cluster({ distance: 100, threshold: 3 })
                
            ],
            styleMap: new OpenLayers.StyleMap(style)
        });;
        map.addLayer(vectorLayer);

        if (b == 2) 
        {           

            ////=================  =========стили для маркеров и тут хранятся координаты

            var features = [];
            for (var i = 0; i < 100; i++) {
                var lon = Math.random() * 2 + -4;
                var lat = Math.random() * 2 + 40;

                var lonlat = new OpenLayers.LonLat(lon, lat);
                lonlat.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));

                var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat));
                features.push(f);
            }
            vectorLayer.addFeatures(features);
          
                

              


        }

Андрей Щ
Новоприбывший
Сообщения: 13
Зарегистрирован: 16 май 2013, 15:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Андрей Щ » 27 май 2013, 09:18

кластеризацию сделал..сейчас маркеры проставляются, но тоже в принципе не быстро....проставляется после того как я закрываю сообщение alert(lon)..

Код: Выделить всё

var strategy = new OpenLayers.Strategy.Cluster({ distance: 20 });
        var vectorLayer = new OpenLayers.Layer.Vector("Overlay", {
            strategies: [strategy],

        });
        map.addLayer(vectorLayer)
        if (b == 2) 
        {           

            var features = [];
            var lon = kor_1;
            var lat = kor_2;
            alert(lon);
            var lonlat = new OpenLayers.LonLat(lon, lat);
            lonlat.transform(new OpenLayers.Projection("EPSG:4326"), new OpenLayers.Projection("EPSG:900913"));

            var f = new OpenLayers.Feature.Vector(new OpenLayers.Geometry.Point(lonlat.lon, lonlat.lat));
            features.push(f);
            
            vectorLayer.addFeatures(features);
        }
        }

есть подозрения,что тормоза из-за того, что в контроллере происходит преобразование каждой кооординаты из вида: 55 66.738603, 51 49 48.116408 в 55.789, 48.678

код контроллера:

Код: Выделить всё

public ActionResult Index()
        {
            List<koordinats_piket> info = new List<koordinats_piket>();

            var result = db.Координаты_пикетов.Select(all => all);

            foreach (var a in result)
            {
              
                    // перевод из формата ddmmss в dddddd
                string[] parts = a.Долгота.Split(' ');
                double Dolgota = 0;
                if (parts.Count() > 0)
                    Dolgota += double.Parse(parts[0].Replace('.', ','));
                if (parts.Count() > 1)
                    Dolgota += double.Parse(parts[1].Replace('.', ',')) / 60d;
                if (parts.Count() > 2)
                    Dolgota += double.Parse(parts[2].Replace('.', ',')) / 3600d;
                string[] parts2 = a.Широта.Split(' ');

                double Shirota = 0;
                if (parts2.Count() > 0)
                    Shirota += double.Parse(parts2[0].Replace('.', ','));
                if (parts2.Count() > 1)
                    Shirota += double.Parse(parts2[1].Replace('.', ',')) / 60d;
                if (parts2.Count() > 2)
                    Shirota += double.Parse(parts2[2].Replace('.', ',')) / 3600d;

                    info.Add(new koordinats_piket
                    {
                        //Shirota = a.Широта,
                        //Dolgota = a.Долгота
                        Shirota = Shirota.ToString().Replace(',', '.'),
                        Dolgota = Dolgota.ToString().Replace(',', '.')
                    });
                    ViewBag.Data = info;
               

            }
return View("Index");
}

Alone
Интересующийся
Сообщения: 31
Зарегистрирован: 20 дек 2011, 23:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Alone » 06 июн 2013, 17:20

cibo писал(а):1500 маркеров это даже не колтчество. Вывожу 100 000 точек на слой тормозов даже не наблюдаю.
Вывожу одновременно 700 видимых на экране точек и векторов на слой, и карта еле тащится...
Использую объекты типа OpenLayers.Feature.Vector
Подскажите, куда копать? Время транспортировки от сервера до клиента в расчет не берем.

Аватара пользователя
Denis Rykov
Гуру
Сообщения: 3376
Зарегистрирован: 11 апр 2008, 21:09
Репутация: 529
Ваше звание: Author
Контактная информация:

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Denis Rykov » 07 июн 2013, 03:58

Серверный рендеринг или кластеризация на клиенте.

[ Сообщение с мобильного устройства ]
Spatial is now, more than ever, just another column- The Geometry Column.

Alone
Интересующийся
Сообщения: 31
Зарегистрирован: 20 дек 2011, 23:32
Репутация: 0

Re: проблема с загрузкой большого количества маркеров в open

Сообщение Alone » 11 июн 2013, 09:54

Если серверный рендеринг, как мне потом при необходимости, подсветить/выделить объект на карте?
Физически то его на клиенте не будет. так?

Ответить

Вернуться в «Веб-картография»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 3 гостя