Javascript 更改OpenLayers标记图标
我对OpenLayers有一个问题。如果我想动态更改某个标记的图标(例如,用另一种颜色绘制标记以指示状态更改),则该标记开始出现错误,没有显示在适当的位置,甚至会留下其自身的半随机副本,在放大或缩小地图时很明显 我已经意识到,当我从一些预加载的图标图像中重新分配marker.icon属性时,问题就发生了,否则这些图像就可以正常工作。我尝试过使用和不使用icon.clone()重新绘制 下面是一个完整但简化的示例,它随机移动标记,并应修改其图标。如果您注释掉“麻烦代码”片段,它运行良好,除了图标更改:Javascript 更改OpenLayers标记图标,javascript,icons,openlayers,marker,Javascript,Icons,Openlayers,Marker,我对OpenLayers有一个问题。如果我想动态更改某个标记的图标(例如,用另一种颜色绘制标记以指示状态更改),则该标记开始出现错误,没有显示在适当的位置,甚至会留下其自身的半随机副本,在放大或缩小地图时很明显 我已经意识到,当我从一些预加载的图标图像中重新分配marker.icon属性时,问题就发生了,否则这些图像就可以正常工作。我尝试过使用和不使用icon.clone()重新绘制 下面是一个完整但简化的示例,它随机移动标记,并应修改其图标。如果您注释掉“麻烦代码”片段,它运行良好,除了图标更
<!DOCTYPE HTML>
<HTML>
<HEAD>
<TITLE>Mapa</TITLE>
<SCRIPT language="javascript" type="text/javascript" src="OpenLayers.js"></SCRIPT>
<SCRIPT language="javascript" type="text/javascript">
var vMapa;
var prj0 = new OpenLayers.Projection("EPSG:4326"); // Transform from WGS 1984
var prj1 = new OpenLayers.Projection("EPSG:900913"); // to Spherical Mercator Projection
var vLon = 12.568142;
var vLat = 55.676320;
var vTimer = null;
var vCont = 0;
</SCRIPT>
</HEAD>
<BODY onClose="vTimer = null; vLon = null; vLat = null;">
<DIV id="demoMap" style="height: 700px; width: 1000px;"></DIV><DIV id="Contador">0</DIV>
<SCRIPT>
var options = {
controls: [
new OpenLayers.Control.Navigation(),
new OpenLayers.Control.PanZoomBar(),
]
};
vMapa = new OpenLayers.Map("demoMap", options);
vMapa.addLayer(new OpenLayers.Layer.OSM());
vMapa.setCenter(new OpenLayers.LonLat(vLon, vLat).transform(prj0, prj1), 15, false, false);
var Navigation = new OpenLayers.Control.Navigation( { defaultDblClick: function(event) { return; } } );
vMapa.addControl(Navigation);
var markers = new OpenLayers.Layer.Markers("Markers");
vMapa.addLayer(markers);
var size = new OpenLayers.Size(12, 12);
var offset = new OpenLayers.Pixel(-6, -6);
var iconOff = new OpenLayers.Icon('img/CircOff.png', size, offset);
var iconOn = new OpenLayers.Icon('img/CircOn.png', size, offset);
var marker = new OpenLayers.Marker(new OpenLayers.LonLat(vLon, vLat).transform(prj0, prj1), iconOff.clone());
marker.setOpacity(1.0);
marker.events.register('mousedown', marker, function(evt) { vMapa.panTo(marker.lonlat); OpenLayers.Event.stop(evt); });
marker.pfInfo = 'Vel: 0.0 km/h';
markers.addMarker(marker);
vTimer = setTimeout('TimerEvent()', 1000);
function TimerEvent() {
vLon += ((Math.random() - 0.5) / 500);
vLat += ((Math.random() - 0.5) / 500);
// ------- Troublesome code -------
var ixIcon = Math.round(Math.random());
if (ixIcon == 0) {
marker.icon = iconOff.clone();
} else {
marker.icon = iconOn.clone();
}
// --------------------------------
var newLonLat = new OpenLayers.LonLat(vLon, vLat).transform(prj0, prj1);
var newPx = marker.map.getLayerPxFromViewPortPx(marker.map.getPixelFromLonLat(newLonLat));
marker.moveTo(newPx);
marker.draw();
vCont ++;
document.getElementById('Contador').innerHTML = vCont;
vTimer = setTimeout('TimerEvent()', 1000);
}
</SCRIPT>
</BODY>
</HTML>
马帕
var-vMapa;
var prj0=新OpenLayers.Projection(“EPSG:4326”);//从WGS 1984转换而来
var prj1=新OpenLayers.Projection(“EPSG:900913”);//球面墨卡托投影
var vLon=12.568142;
var vLat=55.676320;
var vTimer=null;
var vCont=0;
0
变量选项={
控制:[
新建OpenLayers.Control.Navigation(),
新建OpenLayers.Control.PanZoomBar(),
]
};
vMapa=新的OpenLayers.Map(“demoMap”,选项);
vMapa.addLayer(新的OpenLayers.Layer.OSM());
设置中心(新的OpenLayers.LonLat(vLon,vLat).transform(prj0,prj1),15,false,false);
var Navigation=newopenlayers.Control.Navigation({defaultDblClick:function(event){return;}});
vMapa.addControl(导航);
var markers=新的OpenLayers.Layer.markers(“markers”);
vMapa.addLayer(标记);
var size=新的OpenLayers.size(12,12);
var offset=新的OpenLayers.Pixel(-6,-6);
var iconOff=新的OpenLayers.Icon('img/CircOff.png',大小,偏移量);
var iconOn=new OpenLayers.Icon('img/CircOn.png',大小,偏移量);
var marker=new OpenLayers.marker(new OpenLayers.LonLat(vLon,vLat).transform(prj0,prj1),iconOff.clone());
标记物:setOpacity(1.0);
register('mousedown',marker,function(evt){vMapa.panTo(marker.lonlat);OpenLayers.Event.stop(evt);});
marker.pfInfo='Vel:0.0 km/h';
标记。添加标记(标记);
vTimer=setTimeout('TimerEvent()',1000);
函数TimerEvent(){
vLon+=((Math.random()-0.5)/500);
vLat+=((Math.random()-0.5)/500);
//------麻烦代码-------
var ixIcon=Math.round(Math.random());
如果(ixIcon==0){
marker.icon=iconOff.clone();
}否则{
marker.icon=iconOn.clone();
}
// --------------------------------
var newLonLat=newopenlayers.LonLat(vLon,vLat).transform(prj0,prj1);
var newPx=marker.map.getLayerPxFromViewPortPx(marker.map.getPixelFromLonLat(newLonLat));
marker.moveTo(newPx);
marker.draw();
vCont++;
document.getElementById('Contador')。innerHTML=vCont;
vTimer=setTimeout('TimerEvent()',1000);
}
非常感谢您的建议。我从不使用Marker创建标记。 我创建了一个向量层,并添加了点对象。然后对这些点进行风格设计
这工作得更好,功能也更多。您可以创建一个restful web服务,它可以将SVG作为字符串返回。传递的参数将告诉服务图标上必须更改的内容。该服务将读取模板SVG,并对其进行适当的更改和返回。我曾尝试使用矢量层,但迄今为止没有成功。我的标记可以很好地工作,除了图标不能在没有我描述的效果的情况下动态更改。我不知道到底有没有可能做到这一点?