[GIS] OpenLayers Vector KML draw black when change the style

kmlopenlayers-2

I am trying to change the style of an OpenLayers.Vector using radio buttons and redraw it, but the result is a black vector.

I tried own build OpenLayers11 and 12, beside api openlayers hosted.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>
<head>
<title>See kml data</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<meta http-equiv="Content-Style-Type" content="text/css">
<script type="text/javascript" language="javascript" src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">

var osm
var eu;
var Heatmap = new OpenLayers.Style({ 
       id: 1,
       name: 'heatmap',
       fill: true,
       fillColor: '#FF0000',
       fillOpacity: 0.5,
       strokeWidth: 4,
       strokeColor: 'white'
    });

var RG = new OpenLayers.StyleMap({
    "default": new OpenLayers.Style({
       id: 2,
       name: 'rg',
       fill: true,
       fillColor: '#00FF00',
       fillOpacity: 0.5,
       strokeColor: 'white'
    })
    });

var RW = new OpenLayers.Style({
       id: 3,
       name: 'rw',
       fill: true,
       fillColor: '#FFFF00',
       fillOpacity: 0.5,
       strokeColor: 'white'
    }); 

function init() {
var bounds = new OpenLayers.Bounds(
                -1177646.439, 4104612.325,
                3850226.548, 11465970.640
                );

map = new OpenLayers.Map("map", {
    //allOverlays: true,
    maxExtent: bounds,
    //restrictedExtent: bounds
});

//osm =new OpenLayers.Layer.WMS( "Open Street Map",
        //"http://vmap0.tiles.osgeo.org/wms/vmap0",
                //{
                    //layers: 'basic',
                    //isBaseLayer: true,
                    //maxExtent: bounds,
                   // sphericalMercator: true,
                    //visibility: false
                //}
            //);    

kml = new OpenLayers.Layer.Vector("KML", {
        //style: Heatmap,
        isFixed: false,
        strategies: [new OpenLayers.Strategy.BBOX()],
        protocol: new OpenLayers.Protocol.HTTP({
            url: "europe.kml",
            format: new OpenLayers.Format.KML({
                extractStyles: false,
                extractAttributes: false
            })
        })
    });

//kml = new OpenLayers.Layer.GML('KML', 
                //"europe.kml",
                //{
                        //visibility: true,
                        //format: OpenLayers.Format.KML,
                        //style: Heatmap,
                        //projection: map.displayProjection,
                        //strategies: [new OpenLayers.Strategy.BBOX()]
                //}
        //);


map.addLayers([osm, kml]);
map.addControl(new OpenLayers.Control.Scale($('scale')));
map.addControl(new OpenLayers.Control.MousePosition({
            prefix:"long",
            suffix:"lat",
            numDigits:4,
            granularity:true,
    displayProjection:(new OpenLayers.Projection("EPSG:4326"))
            }));
map.addControl(new OpenLayers.Control.LayerSwitcher());
map.addControl(new OpenLayers.Control.KeyboardDefaults());
map.addControl(new OpenLayers.Control.ScaleLine());
map.zoomToExtent(bounds);
}

</head>

<body onload="init()">

  <div id="wrap">

    <div id="header"><h1>See kml data with user styling</h1>

    </div>


<div id="main">

        <div id="map"></div>

</div>

<div id="sidebar"><h1>Select style</h1>
<form name="styleform">
<input name="iStyle1" type="radio" value="heatmap.kml" id="Heatmap" onclick="choosestyle(this.form)">Heatmap</input>
<input name="iStyle2" type="radio" value="RG" id="RG" onclick="choosestyle(this.form)">Red to Green</input>
<input name="iStyle3" type="radio" value="RW" id="RW" onclick="choosestyle(this.form)">Red to White</input>
</form>
</div>

<div id="footer"></div>
</body>
<script type="text/javascript">
function choosestyle(userstyles) {
//alert(userstyles.elements[0].value);
//var userstyle = document.forms[0].elements[iStyle];
//alert(userstyle.length);
for(var i = 0; i < userstyles.length; i++)
   {
   if (userstyles[i].checked)
      {
        kml.style = userstyles[i].value;
    kml.redraw();
    userstyles[i].checked = false;
      }
   }
}
</script>
</html> 

I tried beside an Openlayers.Vector, Openlayers.GML.
I tried beside simple OpenLayers.Style, OpenLayers.StyleMap and server hosted kml style.

The results are shown bellow:

Initial default style

User choosen style

Any clue would help!

Mihai

Edit of the choosestyle(userstyles) function which on the alert returns a style object (checked with Firebug DOM):

function choosestyle(userstyles) {
//alert(userstyles.elements[0].value);
//var userstyle = document.forms[0].elements[iStyle];
//alert(userstyle.length);
for(var i = 0; i < userstyles.length; i++)
   {
   if (userstyles[i].checked)
      {
            kml.style = userstyles[i].value;
        kml.redraw();
            alert(kml.style);
        userstyles[i].checked = false;
      }
   }
}

But the map has the same black color.

Best Answer

There is working example of your application:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> 
<html>
<head>
<title>See kml data</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script>

    var Heatmap = { 
      fill: true,
      fillColor: '#FF0000',
      fillOpacity: 0.5,
      strokeWidth: 4,
      strokeColor: 'white'
    };

    var RG = {
      fill: true,
      fillColor: '#00FF00',
      fillOpacity: 0.5,
      strokeColor: 'white'
    };

    var RW = {
        fill: true,
        fillColor: '#FFFF00',
        fillOpacity: 0.5,
        strokeColor: 'white'
    };

    var styles = {"RW": RW, "RG": RG, "Heatmap": Heatmap};

    function choosestyle(userstyles) {
        for (var i = 0; i < userstyles.length; i++) {
            if (userstyles[i].checked) {
                kml.style = styles[userstyles[i].value];
                kml.redraw();
                userstyles[i].checked = false;
            }
        }
    } 

    function init() {

        var bounds = new OpenLayers.Bounds(-1177646.439, 4104612.325, 3850226.548, 11465970.640);

        map = new OpenLayers.Map("map", {maxExtent: bounds});

        osm =new OpenLayers.Layer.OSM("Open Street Map");    

        kml = new OpenLayers.Layer.Vector("KML", {
                isFixed: false,
                strategies: [new OpenLayers.Strategy.Fixed()],
                protocol: new OpenLayers.Protocol.HTTP({
                    url: "europe.kml",
                    format: new OpenLayers.Format.KML({
                        extractStyles: false,
                        extractAttributes: false
                    })
                })
            });

        map.addLayers([osm, kml]);
        map.zoomToExtent(bounds);
    }
</script>

</head>
<body onload="init()">
<div id="wrap">
<div id="header"><h1>See kml data with user styling</h1>
</div>

<div id="main">
<div id="map" style="width:640px; height:480px;"></div>
</div>

<div id="sidebar"><h1>Select style</h1>
<form name="styleform">
<input name="iStyle1" type="radio" value="Heatmap" id="Heatmap" onclick="choosestyle(this.form)">Heatmap</input>
<input name="iStyle2" type="radio" value="RG" id="RG" onclick="choosestyle(this.form)">Red to Green</input>
<input name="iStyle3" type="radio" value="RW" id="RW" onclick="choosestyle(this.form)">Red to White</input>
</form>
</div>

<div id="footer"></div>
</body>
</html>

There are some mistakes in original code:

  1. OpenLayers.Layer.Vector.style is symbolizer object, not OpenLayers.StyleMap;
  2. userstyles[i].value returns string, not symbolizer, so you need lookup object {"RW": RW, "RG": RG, "Heatmap": Heatmap};
  3. Value of input iStyle1 should be Heatmap.
Related Question