javascriptjsonxmlhttprequestopenlayerspanoramio

OpenLayers Format JSON is Returning Empty responseText String


After a week of posting at the OpenLayers forum and not receiving responses to my questions, I have decided to look here. I have Googled and Googled and Googled and even found a wonderful tutorial concerning this topic, in Spanish, but so well written that Google translate was able to translate it perfectly.

gisandchips.org/2010/05/04/openlayers-y-panoramio/

So I have followed this tutorial and now I am trying to access the Panoramio data API to query photos and display them on my map. However, my code fails at the line:

var panoramio = json.read(response.responseText);

According to firebug and alert(response.responseText), my responseText is an empty string...

In firebug I have the GET url http://localhost/cgi-bin/proxy.cgi?url=http%3A%2F%2Fwww.panoramio.com%2Fmap%2Fget_panoramas.php%3Forder%3Dpopularity%26set%3Dfull%26from%3D0%26to%3D40%26minx%3D-20037508.3392%26miny%3D-20037508.3392%26maxx%3D20037508.3392%26maxy%3D20037508.3392%26size%3Dthumbnail

this shows me valid JSON. And I know my response object isn't null because alert(response) shows that it is getting an [object XMLHttpRequest]

Honestly I am out of ideas. Before trying to parse JSON, I was trying to parse XML and had absolutely no luck. I really like the idea of pulling up RSS and API data onto my map. Below I am attaching my code, I appreciate any feedback you can offer :)

Thank you,

elshae

var map, popup, selectControl, selectedFeature;
var vectorLayer, panoramio_style;

Ext.onReady(function () {
    var options = {
        controls: [new OpenLayers.Control.Navigation()], //Needed to use GeoExt controls such as the zoomslider
        maxExtent: new OpenLayers.Bounds(-20037508.34, -20037508.34, 20037508.34, 20037508.34),
        units: 'm',
        allOverlays: false
    }

    this.map = new OpenLayers.Map(options);

    var ghyb = new OpenLayers.Layer.Google(
            "Google Hybrid",
            {type: google.maps.MapTypeId.HYBRID, numZoomLevels: 20}
    );

    var gmap = new OpenLayers.Layer.Google(
            "Google Streets", // the default
            {type: google.maps.MapTypeId.ROADMAP, numZoomLevels: 20}
    );

    var gphy = new OpenLayers.Layer.Google(
            "Google Physical",
            {type: google.maps.MapTypeId.TERRAIN, numZoomLevels: 20}
            // used to be {type: G_PHYSICAL_MAP}
    );

    var osm = new OpenLayers.Layer.OSM();

    map.addLayers([osm, gphy, gmap, ghyb]);

    OpenLayers.ProxyHost = "http://localhost/cgi-bin/proxy.cgi?url=";

    var mapPanel = new GeoExt.MapPanel({
        title: "Map",
        map: this.map,
        center: new OpenLayers.LonLat(93.9, 29.53).transform(new OpenLayers.Projection("EPSG:4326"),
                new OpenLayers.Projection("EPSG:900913")),
        zoom: 2,
        region: "center"
    });

    //Obtain Bbox coords
    var proj = new OpenLayers.Projection("EPSG:900913");
    var ext = mapPanel.map.getMaxExtent().transform(mapPanel.map.getProjectionObject(), proj);
    var minx = ext.left;
    var miny = ext.bottom;
    var maxx = ext.right;
    var maxy = ext.top;
    alert(minx + " " + miny + " " + maxx + " " + maxy);

    url = "http://www.panoramio.com/map/get_panoramas.php";
    var parameters = {
        order: 'popularity',
        set: 'full',
        from: 0,
        to: 40,
        minx: minx,
        miny: miny,
        maxx: maxx,
        maxy: maxy,
        size: 'thumbnail'
    }

    new Ext.Panel({
        width: 1800,
        height: 600,
        layout: "border",
        renderTo: document.body,
        items: [mapPanel]
    });

    OpenLayers.loadURL(url, parameters, this, showPhotos);
    //alert(OpenLayers.Request.XMLHttpRequest);

});

function showPhotos(response) {

    var json = new OpenLayers.Format.JSON();
    var panoramio = json.read(response.responseText); //Something is wrong here!!!
    var features = new Array(panoramio.photos.length);
    for (var i = 0; i < panoramio.photos.length; i++) {
        var upload_date = panoramio.photos[i].upload_date;
        var owner_name = panoramio.photos[i].owner_name;
        var photo_id = panoramio.photos[i].photo_id;
        var longitude = panoramio.photos[i].longitude;
        var latitude = panoramio.photos[i].latitude;
        var pheight = panoramio.photos[i].height;
        var pwidth = panoramio.photos[i].width;
        var photo_title = panoramio.photos[i].photo_title;
        var owner_url = panoramio.photos[i].owner_url;
        var owner_id = panoramio.photos[i].owner_id;
        var photo_file_url = panoramio.photos[i].photo_file_url;
        var photo_url = panoramio.photos[i].photo_url;

        var fpoint = new OpenLayers.Geometry.Point(longitude, latitude);

        var attributes = {
            'upload_date': upload_date,
            'owner_name': owner_name,
            'photo_id': photo_id,
            'longitude': longitude,
            'latitude': latitude,
            'pheight': pheight,
            'pwidth': pwidth,
            'pheight': pheight,
            'photo_title': photo_title,
            'owner_url': owner_url,
            'owner_id': owner_id,
            'photo_file_url': photo_file_url,
            'photo_url': photo_url
        }

        features[i] = new OpenLayers.Feature.Vector(fpoint, attributes);

    }//Outside for loop

    panoramio_style = new OpenLayers.StyleMap(OpenLayers.Util.applyDefaults({
        pointRadius: 7,
        fillColor: "red",
        fillOpacity: 1,
        strokeColor: "black",
        externalGraphic: "panoramio-marker.png"
    }, OpenLayers.Feature.Vector.style["default"]));

    vectorLayer = new OpenLayers.Layer.Vector("Panoramio Photos", {
        styleMap: panoramio_style
    });

    vectorLayer.addFeatures(features);

    this.map.addLayer(vectorLayer);

    selectControl = new OpenLayers.Control.SelectFeature(vectorLayer,
            {onSelect: onFeatureSelect, onUnselect: onFeatureUnselect});
    this.map.addControl(selectControl);
    selectControl.activate();
}//End showPhotos

// popups
function onPopupClose(evt) {
    selectControl.unselect(selectedFeature);
}

function onFeatureSelect(feature) {
    selectedFeature = feature;

    // HTML del PopUp
    var html = "some HTML I have here";

    popup = new OpenLayers.Popup.FramedCloud("chicken",
            feature.geometry.getBounds().getCenterLonLat(),
            null,
            html,
            null,
            true,
            onPopupClose);

    feature.popup = popup;
    this.map.addPopup(popup);
}

function onFeatureUnselect(feature) {
    this.map.removePopup(feature.popup);
    feature.popup.destroy();
    feature.popup = null;
}

Solution

  • It looks like you have bumped into the Same Origin Policy. You cannot make Ajax requests to hosts outside your domain, unless you use JSONP, or some other technique to get around the policy. Your request to www.panoramio.com is the problem, since I don't think you're hosted on the www.panoramio.com :)

    You may want to check if panoramio offer a JSONP service. Otherwise you could check out the following Stack Overflow post for a few popular solutions to work around the Same Origin Policy (mainly the JSONP, CORS and Reverse Proxy methods):

    And empty responseText is typical of most browsers when they block the response from third-party domains: