Страница 1 из 1

OpenLayers: отслеживание события наведения мыши на объект

Добавлено: 23 май 2012, 10:59
stepan_borovikov
Ребята подскажите плиз.
Мне нужно прослушивать событие когда мышка входит в область линии на карте.

Линию рисую так:

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

<!DOCTYPE html>
<html>
<head>
    <script src="http://openlayers.org/dev/OpenLayers.js"></script>
    <style type="text/css">
    #mapdiv {
        width: 500px;
        height: 500px;
        border: 1px solid #dddddd;
    }
    </style>
 
<script>
function init() {
        map = new OpenLayers.Map("mapdiv");
        var epsg4326 = new OpenLayers.Projection("EPSG:4326");
        var epsg900913 = new OpenLayers.Projection("EPSG:900913");
        //первоначальные координаты
        var center = new OpenLayers.LonLat(60.6340143032,56.8659060093).transform(epsg4326, epsg900913);
        var epsilon = 0.0001;
        //точки
        var points = [
            new OpenLayers.Geometry.Point(center.lon, center.lat),
            new OpenLayers.Geometry.Point(center.lon+1000, center.lat),
            new OpenLayers.Geometry.Point(center.lon, center.lat+1000)
        	      ];
        //стиль к точнам и линиям
        var styles = new OpenLayers.StyleMap({
            "default": new OpenLayers.Style(null, {
                rules: [
                    new OpenLayers.Rule({
                        //объект выделения линии
                        symbolizer: {
                         "Line": {
                                //толщина линии
                                strokeWidth: 20,
                                //прозрачность линии
                                strokeOpacity: 0.5,
                                //цвет линии
                                strokeColor: "#0000FF"
                            }
                        }
                    })
                ]
            }),        });
        //Создание слоёв
        var base = new OpenLayers.Layer.OSM();
        var vectors_lns = new OpenLayers.Layer.Vector("Vector Layer (lines)",  {styleMap: styles});

	map.addLayers([base, vectors_lns]);

        //Добавление объектов в линейный слой
	var feture_d = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points))];
        vectors_lns.addFeatures(feture_d);

	//feture_d.events.register('mouseover', vectors_lns, function(evt) {alert('dsds')});

        map.setCenter(center, 15);
    }
</script>

</head>
<body onload="init()">
    <div id="mapdiv"></div>
</body>
</html>


Как назначить прослушиватель события на факт вхождения мыши в пределы линии?
Заранее благодарен.

Re: OL: Разделить линию, не используя OpenLayers.Control.Spl

Добавлено: 23 май 2012, 11:17
Denis Rykov
Например, так:

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


map.addControl(new OpenLayers.Control.SelectFeature(
vectors_lns,
{
hover: true,
onSelect: function() {
alert("Don't touch me!")
},
autoActivate: true
})
);

Re: OL: Разделить линию, не используя OpenLayers.Control.Spl

Добавлено: 23 май 2012, 11:38
stepan_borovikov
огромное спасибо. Но есть еще нюансик. Если линий несколько, то для каждой должен быть назначен отдельный слушатель. Вот код с двумя линиями.

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

<!DOCTYPE html>
<html>
<head>
    <script src="http://openlayers.org/dev/OpenLayers.js"></script>
    <style type="text/css">
    #mapdiv {
        width: 1000px;
        height: 1000px;
        border: 1px solid #dddddd;
    }
    </style>
 
<script>
function init() {
        map = new OpenLayers.Map("mapdiv");
        var epsg4326 = new OpenLayers.Projection("EPSG:4326");
        var epsg900913 = new OpenLayers.Projection("EPSG:900913");
        //первоначальные координаты
        var center = new OpenLayers.LonLat(60.6340143032,56.8659060093).transform(epsg4326, epsg900913);
        var center2 = new OpenLayers.LonLat(60.6320143032,56.8259060093).transform(epsg4326, epsg900913);
        var epsilon = 0.0001;
        //точки
        var points = [
            new OpenLayers.Geometry.Point(center.lon, center.lat),
            new OpenLayers.Geometry.Point(center.lon+1000, center.lat),
            new OpenLayers.Geometry.Point(center.lon, center.lat+1000)
        	      ];

        var points2 = [
            new OpenLayers.Geometry.Point(center2.lon +8, center2.lat + 9),
            new OpenLayers.Geometry.Point(center2.lon+1000, center2.lat),
            new OpenLayers.Geometry.Point(center2.lon + 9, center2.lat+900)
        	      ];

        //стиль к точнам и линиям
        var styles = new OpenLayers.StyleMap({
            "default": new OpenLayers.Style(null, {
                rules: [
                    new OpenLayers.Rule({
                        //объект выделения линии
                        symbolizer: {
                         "Line": {
                                //толщина линии
                                strokeWidth: 20,
                                //прозрачность линии
                                strokeOpacity: 0.5,
                                //цвет линии
                                strokeColor: "#0000FF"
                            }
                        }
                    })
                ]
            }),        });
        //Создание слоёв
        var base = new OpenLayers.Layer.OSM();
        var vectors_lns = new OpenLayers.Layer.Vector("Vector Layer (lines)",  {styleMap: styles});


map.addControl(new OpenLayers.Control.SelectFeature(
   vectors_lns,
   {
     hover: true,
     onSelect: function() {
       alert("Don't touch me!")
     },
     autoActivate: true
   })
 );
 

	map.addLayers([base, vectors_lns]);

        //Добавление объектов в линейный слой
	var feture_d = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points))];
        vectors_lns.addFeatures(feture_d);

	feture_d = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points2))];
        vectors_lns.addFeatures(feture_d);


	//feture_d.events.register('mouseover', vectors_lns, function(evt) {alert('dsds')});

        map.setCenter(center, 12);
    }
</script>

</head>
<body onload="init()">
    <div id="mapdiv"></div>
</body>
</html>


я делаю что то подобное с картинками вот так:

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

...
var marker = new OpenLayers.Marker(lonLatMarker, icon);
marker.events.register('dblclick', feature, function(evt) {dblclick_to(id,unit)});
...
тут id это код элемента в справочнике, а unit это тип объекта. т.е. при возникновении события в dblclick_to прилетает id того объекта на котором нажали кнопку.

Как сделать подобное с линиями?

Спасибо.

Re: OL: Разделить линию, не используя OpenLayers.Control.Spl

Добавлено: 23 май 2012, 11:45
Denis Rykov
Ну передавайте в onSelect фичу, а внутри самой функции вызывайте нужный вам атрибут этой фичи - id там или что угодно:

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


map.addControl(new OpenLayers.Control.SelectFeature(
vectors_lns,
{
hover: true,
onSelect: function(f) {
alert(f.geometry.id);
},
autoActivate: true
})
);

Re: OL: Разделить линию, не используя OpenLayers.Control.Spl

Добавлено: 23 май 2012, 11:59
stepan_borovikov
т.е. в методе
var feture_d = [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points))];

как то нужно добавить два атрибута которые я помом смогу прочесть в

onSelect: function(f) {
alert(f.geometry.id);
},
.....

а как эти атрибуты туда добавить? Наверное совсем делетанский вопрос, за что прошу прощения.

Re: OL: Разделить линию, не используя OpenLayers.Control.Spl

Добавлено: 23 май 2012, 12:15
Denis Rykov
Это всё описано в документации:

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


vectors_lns.addFeatures([
new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.LineString(points),
{
attr1: "1",
attr2: "2",
attrN: "3"
}
),
new OpenLayers.Feature.Vector(
new OpenLayers.Geometry.LineString(points2),
{
attr1: "4",
attr2: "5",
attrN: "6"
}
)
]);


Аттрибуты фичи доступны как f.attributes.attrN.

Re: OpenLayers: отслеживание события наведения мыши на объек

Добавлено: 23 май 2012, 12:31
stepan_borovikov
Все заработало как нужно. Огромное спасибо.
Читать доки я пытался но разобраться в том что там пишут как то не получилось.

рабочий код ниже:

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

<!DOCTYPE html>
<html>
<head>
    <script src="http://openlayers.org/dev/OpenLayers.js"></script>
    <style type="text/css">
    #mapdiv {
        width: 1000px;
        height: 1000px;
        border: 1px solid #dddddd;
    }
    </style>
 
<script>
function init() {
        map = new OpenLayers.Map("mapdiv");
        var epsg4326 = new OpenLayers.Projection("EPSG:4326");
        var epsg900913 = new OpenLayers.Projection("EPSG:900913");
        //первоначальные координаты
        var center = new OpenLayers.LonLat(60.6340143032,56.8659060093).transform(epsg4326, epsg900913);
        var center2 = new OpenLayers.LonLat(60.6320143032,56.8259060093).transform(epsg4326, epsg900913);
        var epsilon = 0.0001;
        //точки
        var points = [
            new OpenLayers.Geometry.Point(center.lon, center.lat),
            new OpenLayers.Geometry.Point(center.lon+1000, center.lat),
            new OpenLayers.Geometry.Point(center.lon, center.lat+1000)
        	      ];

        var points2 = [
            new OpenLayers.Geometry.Point(center2.lon +8, center2.lat + 9),
            new OpenLayers.Geometry.Point(center2.lon+1000, center2.lat),
            new OpenLayers.Geometry.Point(center2.lon + 9, center2.lat+900)
        	      ];

        //стиль к точнам и линиям
        var styles = new OpenLayers.StyleMap({
            "default": new OpenLayers.Style(null, {
                rules: [
                    new OpenLayers.Rule({
                        //объект выделения линии
                        symbolizer: {
                         "Line": {
                                //толщина линии
                                strokeWidth: 20,
                                //прозрачность линии
                                strokeOpacity: 0.5,
                                //цвет линии
                                strokeColor: "#0000FF"
                            }
                        }
                    })
                ]
            }),        });
        //Создание слоёв
        var base = new OpenLayers.Layer.OSM();
        var vectors_lns = new OpenLayers.Layer.Vector("Vector Layer (lines)",  {styleMap: styles});


	map.addLayers([base, vectors_lns]);

        //Добавление объектов в линейный слой
	var feture_d 	= [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points),{attr1: "DR1"})];
	var feture_d2 	= [new OpenLayers.Feature.Vector(new OpenLayers.Geometry.LineString(points2),{attr1: "DR2"})];

	map.addControl(new OpenLayers.Control.SelectFeature(
    		vectors_lns,
		    {
		      hover: true,
		      onSelect: function(f) {
		        alert(f.attributes.attr1);
		      },
		      autoActivate: true
		    })
		  );
 

        vectors_lns.addFeatures(feture_d);
        vectors_lns.addFeatures(feture_d2);
        map.setCenter(center, 12);
    }
</script>

</head>
<body onload="init()">
    <div id="mapdiv"></div>
</body>
</html>


Re: OpenLayers: отслеживание события наведения мыши на объек

Добавлено: 23 май 2012, 23:09
stepan_borovikov
Обнаружил проблему с прослущиванием события:

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

    map.addControl(new OpenLayers.Control.SelectFeature(
          vectors_lns,
          {
            click: true,
            onSelect: function(f) {
              alert(f.attributes.attr1 + " " + f.attributes.attr2);
            }
            ,
            autoActivate: true
          })
        );
если активирован этот Control и слой "vectors_lns" видимый, то перестают срабатывать события для элементов в других слоях. События в слое "vectors_lns" работаю.

В двух других слоях находятся иконки с различными изображениями, и должны реагировать на наведение и шелчек мыши. Иконки в другом слое добавляю так

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

 function setMarker(lon, lat, id, unit){
...
   layer_auto = new OpenLayers.Layer.Markers("layer_auto");
   map.addLayer(layer_auto);

   var lonLatMarker = new OpenLayers.LonLat(lon,lat).transform
          (
            new OpenLayers.Projection("EPSG:4326"),
            new OpenLayers.Projection("EPSG:900913") 
          );   
    var feature = new OpenLayers.Feature(layer_auto, lonLatMarker);
    var size = new OpenLayers.Size(30,30);
    var icon = new OpenLayers.Icon('./resources/images/Видеокамера.ico');
    var marker = new OpenLayers.Marker(lonLatMarker, icon);

   //назначаю событие для маркера так
   marker.events.register('mouseover', feature, function(evt) {map_mouseover(id,unit)});
....

   layer_auto.addMarker(marker);
вот как раз событие
marker.events.register('mouseover', feature, function(evt) {map_mouseover(id,unit)});
перестает происходить.
Я так понимаю что лайер "vectors_lns" перекрывает всю поверхность отчего события в других слоях не срабатывают.

Как прослушивать события в всех (всего их три) слоях?

Спасибо.

Re: OpenLayers: отслеживание события наведения мыши на объек

Добавлено: 24 май 2012, 05:35
Denis Rykov
Во-первых, откажитесь от маркеров и используйте вместо них векторные объекты. Во-вторых, передавайте в контрол SelectFeature не один слой, а массив. И в-третьих, внутри функции onSelect в зависимости от слоя к которому принадлежит объект пишите свой обработчик. Вот набросал небольшой пример здесь.

Re: OpenLayers: отслеживание события наведения мыши на объек

Добавлено: 24 май 2012, 15:01
stepan_borovikov
Очень признателен вам за помощь.
У меня все заработало.

Выложу код на прослушивание нескольких событий. Пришлось чуточку полазить по просторам интернета.

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

     layer_rout = new OpenLayers.Layer.Vector("Автомобильные дороги",  {styleMap: styles});

     map.addLayer(layer_kms_meteo_cam); 
     map.addLayer(layer_rout);
     map.addLayer(layer_CarDtpWinter);
     

     map.addControl(
        new OpenLayers.Control.SelectFeature(
          [layer_kms_meteo_cam,layer_rout, layer_CarDtpWinter],
          {
              click: true
             ,hover: true
             ,callbacks:{
                     'over' : function(f) {map_mouseover(f.attributes.attr1, f.attributes.attr2);}
                    ,'out'  : function(f) {map_mouseout(f.attributes.attr1, f.attributes.attr2);}
                    ,'click': function(f) 
                            {
                                if          (f.layer.name === 'столбики станции камеры'  || f.layer.name === 'ДТП погода автомобили'){
                                    map_mouseclick(f.attributes.attr1, f.attributes.attr2);
                                }
                                else if     (f.layer.name === 'Автомобильные дороги'){
                                    alert(f.layer.name);
                                }
                                
                            }
                        }
             ,autoActivate: true
          })
        );