Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I am trying to read geographic data from MS SQL Server 2012 and display it using the JavaScript library OpenLayers in an MVC4 view. I can confirm that the data leaves MVC OK but I have problem is getting the data to be processed by OpenLayers. I have tried two approaches: a) using OpenLayers.Protocol.Script and b) using $.getJSON to read the data and adding using addfeatures. Both fail for different reasons. I will describe the method using OpenLayers.Protocol.Script as it is the preferred method.

My MVC View looks like this:

<body onload="init()">
<h2>Open Layers - Two layer from SQL, Massive</h2>
<div id="map-canvas"></div>
</body>
@section scripts {
<script src="http://maps.google.com/maps/api/js?sensor=false"></script>
<script src="http://openlayers.org/api/OpenLayers.js"></script>

<script type="text/javascript">
    var map, layer1, layer1;

    function init() {
        var proj_4326 = new OpenLayers.Projection('EPSG:4326');
        var proj_900913 = new OpenLayers.Projection('EPSG:900913');
        map = new OpenLayers.Map({
            div: "map-canvas",
            projection: proj_900913,
            displayProjection: proj_4326,
            numZoomLevels: 21,
            maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34)
        });

        var google_base_layer = new OpenLayers.Layer.Google("Google Streets", {
            sphericalMercator: true,
            baselayer: true
        });
        map.addLayer(google_base_layer);

        //Create an array of strategy objects
        var vector_strategies = [new OpenLayers.Strategy.Fixed()];

        var wktReader = new OpenLayers.Format.WKT();

        var layer1 = new OpenLayers.Layer.Vector("Layer 1", {
            projection: proj_4326,
            strategies: vector_strategies,
            protocol: new OpenLayers.Protocol.Script({
                url: "GetGeoLayerData",
                params: { layerId: 1 },
                format: new OpenLayers.Format.JSON({
                    read: function(json) {
                        var features = [];
                        $.each(json, function(i, item) {
                            var feature = wktReader.read(item.wktgeography);
                            feature.attributes = { value: item.value, info: item.info };
                            features.push(feature);
                        });
                        return features;
                    }
                })
            })
        });

        map.addLayer(layer1);

        // Add a layer switcher control
        map.addControl(new OpenLayers.Control.LayerSwitcher({}));

        if (!map.getCenter()) {
            map.zoomToMaxExtent();
        }
    }
</script>
}

And my MVC action that responds to the OpenLayers.Protocol.Script looks like this (note that the field 'Location' is of type DbGeography and .ToString() returns the WKT version of the geography). The service simply returns a IQueryable of type IGeoItem.

public JsonResult GetGeoLayerData( int layerId, IServiceGetSpecificList<IGeoItem, int> service)
    {
        var formattedData = service.GetSpecificList(layerId).Select(x => 
            new { wktgeography = x.Location.AsText(), value = x.Value, info = x.Info });
        return Json(formattedData, JsonRequestBehavior.AllowGet);
    }

What happens is:

  1. A request to the MVC action happens and a valid JSON result is handed back (as seen by FireBug NET console).
  2. The read function never gets called (checked with Firebug breakpoint and Console.Log message).
  3. ... Therefore no vector features are added to layer1.

I would appreciate help on solving this as I have tried a number of approaches and none of them work. Maybe I have made a silly mistake but I can't see it. Thanks in advance.

UPDATE with solution:

Following the advice from cavila (see below) I have fixed this problem. The change was in the definition of the Vector layer protocol from Script to HTTP. I have included just that section of the view below in case it helps anyone else

var layer1 = new OpenLayers.Layer.Vector("Layer 1", {
    projection: proj_4326,
    strategies: vector_strategies,
    protocol: new OpenLayers.Protocol.HTTP({
        url: "GetGeoLayerData?layerId=1",
        format: new OpenLayers.Format.JSON({
            read: function(jsonp) {
                var features = [];
                $.each($.parseJSON(jsonp), function(i, item) {
                    var feature = wktReader.read(item.wktgeography);
                    feature.attributes = { value: item.value, info: item.info };
                    features.push(feature);
                });
                return features;
            }
        })
    })
});
share|improve this question
add comment

1 Answer 1

The protocol OpenLayers.Protocol.Script is to be used with JSONP. I guess you missing the function to be called in responde with this protocol.

Replace it with OpenLayers.Protocol.HTTP.

share|improve this answer
    
Hi @cavila, thanks for that. Yes, HTTP did the trick. However HTTP seems to return JSONP, not JSON, but easily fixed. I still don't really see what I did wrong with OpenLayers.Protocol.Script, but I am happy to get a fix. Thanks for your help. PS. I have added a update to my question to show the solution in case it helps anyone else. –  Jon Smith Dec 23 '12 at 18:04
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.