How to Use SLD File with OpenLayers for OSM Data

openlayers-2openstreetmapsldstylevector

My app, made with openlayers, displays building data called from overpass api.

var data_url = "http://overpass-api.de/api/interpreter?data=(way[building](bbox);node(w););out body;"; //main working url
var building = new OpenLayers.Layer.Vector("Building", {
        strategies: [new OpenLayers.Strategy.BBOX({ratio:0.75})],
        protocol: new OpenLayers.Protocol.HTTP({
            url: data_url,   //<-- relative or absolute URL to your .osm file
            format: new OpenLayers.Format.OSM()
        }),
        projection: new OpenLayers.Projection("EPSG:4326")
    });

Now i need to render them according the builing tag (commercial, yes, school etc). As of now i am using the Openlayers.Style to define each class.

var stylemap = new OpenLayers.StyleMap({
        "default": new OpenLayers.Style({
            strokeColor: "white",
            strokeWidth: 1
        }, {
            rules: [
                new OpenLayers.Rule({
                    filter: new OpenLayers.Filter.Comparison({
                        type: OpenLayers.Filter.Comparison.EQUAL_TO,
                        property: "building",
                        value: "yes"
                    }),
                    symbolizer: {
                        fillColor: "olive"
                    }
                })
            ]
        })
    })

The thing is i have made a sld file from the same data using Quantum GIS.

<?xml version="1.0" encoding="UTF-8"?>

<StyledLayerDescriptor xmlns="http://www.opengis.net/sld" xmlns:ogc="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/sld http://schemas.opengis.net/sld/1.1.0/StyledLayerDescriptor.xsd" xmlns:se="http://www.opengis.net/se">
  <NamedLayer>
    <se:Name>interpreter polygons</se:Name>
    <UserStyle>
      <se:Name>interpreter polygons</se:Name>
      <se:FeatureTypeStyle>
        <se:Rule>
          <se:Name>commercial</se:Name>
          <se:Description>commercial</se:Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>building</ogc:PropertyName>
              <ogc:Literal>commercial</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#a6611a</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.26</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>office</se:Name>
          <se:Description>office</se:Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>building</ogc:PropertyName>
              <ogc:Literal>office</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#d3ae69</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.26</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>school</se:Name>
          <se:Description>school</se:Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>building</ogc:PropertyName>
              <ogc:Literal>school</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#ece0c5</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.26</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>warehouse</se:Name>
          <se:Description>warehouse</se:Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>building</ogc:PropertyName>
              <ogc:Literal>warehouse</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#c6e5e0</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.26</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
        <se:Rule>
          <se:Name>yes</se:Name>
          <se:Description>yes</se:Description>
          <ogc:Filter>
            <ogc:PropertyIsEqualTo>
              <ogc:PropertyName>building</ogc:PropertyName>
              <ogc:Literal>yes</ogc:Literal>
            </ogc:PropertyIsEqualTo>
          </ogc:Filter>
          <se:PolygonSymbolizer>
            <se:Fill>
              <se:SvgParameter name="fill">#66beb1</se:SvgParameter>
            </se:Fill>
            <se:Stroke>
              <se:SvgParameter name="stroke">#000000</se:SvgParameter>
              <se:SvgParameter name="stroke-width">0.26</se:SvgParameter>
            </se:Stroke>
          </se:PolygonSymbolizer>
        </se:Rule>
      </se:FeatureTypeStyle>
    </UserStyle>
  </NamedLayer>
</StyledLayerDescriptor>

I want openlayers to read this sld file, parse and create a stylemap from it, and use the style in vector(building) layer.

P.S. I hve alread gone through the Openlayers Dev Example.

Edited:
The full app

<html>
<head>
<title>WebDRI</title>
<link rel="stylesheet" href="http://openlayers.org/api/2.12/theme/default/style.css" type="text/css">
<!--link rel="stylesheet" href="../../openlayers/theme/default/style.css" type="text/css"-->
<!--link rel="stylesheet" href="osmparser.css" type="text/css"-->
<script src="http://openlayers.org/api/2.12/OpenLayers.js" type="text/javascript"></script>
<!--script src="../../openlayers-2.12/OpenLayers.js"></script-->
<script src="http://ecn.dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2&amp;mkt=en-us"></script> <!--This is required wrapper for the bing images-->
<script src="http://www.openstreetmap.org/openlayers/OpenStreetMap.js"></script>
<!--script src="../OpenStreetMap.js"></script-->
<style>
    html, body, #map {margin: 0; width: *; height: 90%;}
</style>
<script type="text/javascript">
    //OpenLayers.ProxyHost= "/cgi-bin/proxy.cgi?url=";
    //map options
    var map;
    var centerX = 85.346778;//491213.721224323//-123.1684986291807;//9497800;
    var centerY = 27.724879;//5456645.24607268//49.245339757767844;//3212000;
    var center = new OpenLayers.LonLat(centerX, centerY);
    var range = 0.0005;//10000000//.5;//10000;
    var map_bound = [centerX-range,centerY-range,centerX+range,centerY+range];
    var extent = new OpenLayers.Bounds(map_bound[0],map_bound[1],map_bound[2],map_bound[3]);
    var zoom = 17;
    var zoom_data_limit = 18; // vector data will load only in this level or above

    //other options
    var proj4326 = new OpenLayers.Projection("EPSG:4326");
    var proj900913 = new OpenLayers.Projection("EPSG:900913");
    var popup;

    var field = ["name","amenity","building"];

function submit(){
    alert(document.getElementById('name'));
}

function init(){
    //map configuration
    map = new OpenLayers.Map('map',{
        //allOverlays:true,
        maxExtent:extent,
        controls:[new OpenLayers.Control.PanZoomBar(),
            new OpenLayers.Control.MousePosition({
                suffix:'',
                emptyString:'',
                displayProjection:new OpenLayers.Projection("EPSG:4326")
            }),
            new OpenLayers.Control.ScaleLine(),
            new OpenLayers.Control.Scale(),
            new OpenLayers.Control.Navigation(),
            new OpenLayers.Control.LayerSwitcher(),
            new OpenLayers.Control.Attribution()
        ],
        projection:proj4326,
        displayProjection:proj900913
    });
    bing = new OpenLayers.Layer.Bing({name: "Bing Aerial Layer",type: "Aerial",key: "AqTGBsziZHIJYYxgivLBf0hVdrAk9mWO5cQcb8Yux8sW5M8c8opEC2lZqKR1ZZXf",});
    osm = new OpenLayers.Layer.OSM("OSM");
    map.addLayer(osm);
    map.addLayer(bing);
    map.setCenter(center.transform(proj4326,proj900913));
    //map.setCenter(center);
    map.zoomTo(zoom);

    var stylemap = new OpenLayers.StyleMap({
        "default": new OpenLayers.Style({
            strokeColor: "white",
            strokeWidth: 1
        }, {
            rules: [
                new OpenLayers.Rule({
                    filter: new OpenLayers.Filter.Comparison({
                        type: OpenLayers.Filter.Comparison.EQUAL_TO,
                        property: "building",
                        value: "yes"
                    }),
                    symbolizer: {
                        fillColor: "olive"
                    }
                })
            ]
        })
    })

    //OSM data layer
    ///api/0.6/map?bbox=left,bottom,right,top
    var osm_url = "http://openstreetmap.org/api/0.6/map?bbox=";
    //alert("/api/0.6/map?bbox=left,bottom,right,top"+extent.toString());
    //var data_url = osm_url+extent.toString();
    //alert(data_url);
    //document.getElementById('title').innerHTML = data_url;
    var data_url = "http://overpass-api.de/api/interpreter?data=(way[building](bbox);node(w););out body;"; //main working url
    //var data_url = "Ktm valley 2013-01-01_10-47.osm";
    //var data_url = "http://overpass-api.de/api/interpreter?data=%28way%5B%22building%22%3D%22yes%22%5D%28"+map_bound[1]+"%2C"+map_bound[0]+"%2C"+map_bound[3]+"%2C"+map_bound[2]+"%29%3B%3E%3B%29%3Bout%20body%3B%0A";//building=yes

    var building = new OpenLayers.Layer.Vector("Building", {
        strategies: [new OpenLayers.Strategy.BBOX({ratio:0.75})],
        protocol: new OpenLayers.Protocol.HTTP({
            url: data_url,   //<-- relative or absolute URL to your .osm file
            format: new OpenLayers.Format.OSM()
        }),
        projection: new OpenLayers.Projection("EPSG:4326"),
        styleMap: stylemap
    });

    map.events.on({
        "zoomend":function(e){
            if(this.getZoom()>=zoom_data_limit){        //sufficiently zoomed in now load vertor data
                if(!map.getLayersByName("Building")[0]){
                    if(map.baseLayer.name=="OSM"){
                        if(confirm("Do you want to change to Bing Satellite Image?")){
                            map.setBaseLayer(bing);
                        }
                    }
                    map.addLayer(building);

                }
                document.getElementById('instructionline').innerHTML = "Click on the Building to see details";
            }
            else{
                if(map.getLayersByName("Building")[0]){
                    if(map.baseLayer.name=="Bing Aerial Layer"){
                        if(confirm("Do you want to change to OSM Layer?")){
                            map.setBaseLayer(osm);
                        }
                    }
                    map.removeLayer(building);
                    document.getElementById('instructionline').innerHTML = "Zoom in to View Data";
                }
            }
        }
    }); 

    //this part shows the bounding boxes of the map
    var boxes = new OpenLayers.Layer.Vector("Extent",{
        projection: new OpenLayers.Projection("EPSG:900913")
    });

    boxes.addFeatures([new OpenLayers.Feature.Vector(
        extent.transform(proj4326,proj900913).toGeometry()
    )]);
    //map.addLayers([boxes]);
    //map.zoomToExtent(extent);
    //map.zoomToExtent(extent.transform(proj4326,proj900913));
    //controls
    function onPopupClose(evt) {
        selector.unselect(selectedfeature);
    }

    function onFeatureUnselect(feature){
        if(feature.popup)
        {   feature.popup.destroy();   //removes popup from previously selected feature on selecting new feature
        }
    }

    function onFeatureSelect(feature) {
        selectedfeature = feature;
        var szHTML = "<div style='font-size:10'><h1>Road form</h1>"
           + "<div id='roadFormInPopup'></div>"
           + "</div>";
        var text = "<div id='form'><ul>OSM id:"+selectedfeature.osm_id;      //first line of popup
        for (var i in field) {  //lists all fieldibutes
            key = field[i];
            val = selectedfeature.attributes[field[i]];
            if(val){
                text += "<li>" + key + " : " + "<input type='text' id='" + key + "' value='" + val + "'></input></li>";
            }
            else{
                text += "<li>" + key + " : " + "<input type='text' id='" + key + "' value='" + "Please select one from list" + "'></input></li>";
            }
        }
        text +="<input id='save' type='button' value='Save' onClick='submit();'/></ul></div>";
        var htmlCode = '<div id="div1">'+feature.osm_id+'<form target="_blank"><table><tr><td> Building </td><td> <select id="bldg"><option value="Old">Old</option><option value="New">New</option>    </select></td></tr><tr><td> Stories </td><td> <select id="stry"><option value="Single">Single</option><option value="Multiple">Multiple</option></select></td>  </tr></table><input type="button" value="Submit" onclick="loadXMLDOC('+feature.osm_id+')"/></form></div>';
        popup = new OpenLayers.Popup.FramedCloud(
            "chicken",
            selectedfeature.geometry.getBounds().getCenterLonLat(),
            null,
            //htmlCode,
            //szHTML,
            text,
            null,
            true,
            onPopupClose
        );
        popup.updateSize();
        feature.popup = popup;
        map.addPopup(feature.popup);
    }

    function onHover(feature) {
        //alert(feature.CLASS_NAME);
    }

    /*var highlighter = new OpenLayers.Control.SelectFeature(building,{
        hover:true,
        highlightOnly:true,
        eventListeners: {featurehighlighted: onHover}
    });
    map.addControl(highlighter);
    highlighter.activate();
    */
    var selector = new OpenLayers.Control.SelectFeature(building,{
        onSelect: onFeatureSelect,
        onUnselect: onFeatureUnselect
    });
    map.addControl(selector);
    selector.activate();
}
</script>

WEB DRI Building Structure Data Collection App
Zoom In to view data

Best Answer

you need to assign the styles of sld to vector.

  1. Create a sld format object using OpenLayers.Format.SLD and Openlayers.Request.GET
  2. assign the style to vector using style or stylemap

    var format = new OpenLayers.Format.SLD();
    OpenLayers.Request.GET({
        url: "yoursldfile.sld",
        success: sldparser
    });
    function sldparser(req) {
        sld = format.read(req.responseXML || req.responseText);
        styles = sld.namedLayers.interpreted.userStyles[0];
        building_vec.styleMap.styles.default = styles;
    }