New at Leaflet New at Leaflet - 13 days ago 5
Ajax Question

How to add a layer in openlayer3 using ajax?

I am new to Openlayers3.....I am trying to load data from database using ajax & php to load vector data to openlayers3,I am stuck and don't know what is the problem.
here is my code
Can anyone help me in that?

$(document).ready(function()
{
//extent of the map
view = new ol.View({
center:ol.proj.transform([125.7799,8.7965], 'EPSG:4326', 'EPSG:3857'),
zoom:11,
maxZoom:18,
minZoom:2
});

//BaseLayer
var baseLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});

// create a vector source that loads a GeoJSON file
var vectorSource = new ol.source.Vector({
projection: 'EPSG:4326',
url: 'data/Boundaries.geojson',
format: new ol.format.GeoJSON()

});

var geoJSONFormat = new ol.format.GeoJSON();

var farmersSource = new ol.source.Vector({
loader: function(extent, resolution, projection) {
var url = 'allfarmers_geojson.php?p=' + extent.join(',');
$.ajax({
url: url,
success: function(data) {
var features = geoJSONFormat.readFeatures(data);
farmersSource.addFeatures(features);
}
});
},
strategy: ol.loadingstrategy.bbox
});


// Polygons
var createPolygonStyleFunction = function() {
return function(feature, resolution) {
var style = new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 1

}),
fill: new ol.style.Fill({
color: '#faeaac'
}),
//text: createTextStyle(feature)
});
return [style];
};
};

// a vector layer to render the source
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style:createPolygonStyleFunction()

});

var farmersLayer = new ol.layer.Vector({
source: farmersSource
//style:createPolygonStyleFunction()

});

//Map
var map = new ol.Map({
target:'map',
controls:ol.control.defaults().extend([
new ol.control.ScaleLine(),
new ol.control.ZoomSlider()
]),
renderer: 'canvas',
layers:[baseLayer,vectorLayer,farmersLayer],
view:view
});

//////////styling features and with mouse over color change/////////////
var highlightStyleCache = {};

var featureOverlay = new ol.layer.Vector({
source: new ol.source.Vector(),
map: map,
style: function(feature, resolution) {
var text = resolution < 5000 ? feature.get('NAME_3') : '';
if (!highlightStyleCache[text]) {
highlightStyleCache[text] = new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#f00',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.1)'
}),
text: new ol.style.Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new ol.style.Fill({
color: '#f00'
})
})
});
}
return highlightStyleCache[text];
}
});

var highlight;
var displayFeatureInfo = function(pixel) {

var feature = map.forEachFeatureAtPixel(pixel, function(feature) {
return feature;
});

if (feature !== highlight) {
if (highlight) {
featureOverlay.getSource().removeFeature(highlight);
}
if (feature) {
featureOverlay.getSource().addFeature(feature);
}
highlight = feature;
}

};

map.on('pointermove', function(evt) {
if (evt.dragging) {
return;
}
var pixel = map.getEventPixel(evt.originalEvent);
displayFeatureInfo(pixel);
});

map.on('click', function(evt) {
displayFeatureInfo(evt.pixel);
});
//////////End of styling features and with mouse over color change/////////////

});


and here is my php file

<?php
$conn = new PDO('mysql:host=localhost;dbname=FarmersDB','root','admin');

$sql = 'SELECT *, _coordinates__latitude AS x, _coordinates__longitude AS y FROM farmers';

if (isset($_GET['bbox']) || isset($_POST['bbox'])) {
$bbox = explode(',', $_GET['bbox']);
$sql = $sql . ' WHERE x <= ' . $bbox[2] . ' AND x >= ' . $bbox[0] . ' AND y <= ' . $bbox[3] . ' AND y >= ' . $bbox[1];
}

$rs = $conn->query($sql);
if (!$rs) {
echo 'An SQL error occured.\n';
exit;
}

$geojson = array(
'type' => 'FeatureCollection',
'features' => array()
);


while ($row = $rs->fetch(PDO::FETCH_ASSOC)) {
$properties = $row;

unset($properties['x']);
unset($properties['y']);
$feature = array(
'type' => 'Feature',
'geometry' => array(
'type' => 'Point',
'coordinates' => array(
$row['x'],
$row['y']
)
),
'properties' => $properties
);

array_push($geojson['features'], $feature);
}

header('Content-type: application/json');
echo json_encode($geojson, JSON_NUMERIC_CHECK);
$conn = NULL;
?>

Answer

No exactly sure what problem you're having but try this..You probably need to set the right projection and parse the data response from the server..Projection is EPSG:3857 by default:

  success: function(data) {
    var JSONData;
      try {
        JSONData = JSON.parse(data);
      } catch(err) {
        alert(err);
        return;
      }
      var format = new ol.format.GeoJSON();
      var features = format.readFeatures(JSONData, {
            featureProjection: 'EPSG:3857'
      });
      farmersSource.addFeatures(features);
      farmersSource.changed();
    }
   });

Also, on var vectorSource change the project to EPSG:3857. Another thing, you need to add the vectorloader property to you source.vector. For example:

 var locationSource = new ol.source.Vector({
   url: loc_url,
   format: new ol.format.GeoJSON({
    defaultDataProjection :'EPSG:3857' 
   }),
   loader: vectorLoader,
   strategy: ol.loadingstrategy.all
 });

The vectorLoader function looks like this and makes your ajax calls to the server. Special note on loader functions - When clear() is called on the source layer, it will trigger the vector loader function again:

var vectorLoader = function(extent, resolution, projection) {
  var url = this.getUrl();
   utils.refreshGeoJson(this);
}


var utils = {
  refreshGeoJson: function(source,url) {
    var now = Date.now();
    if (typeof url == 'undefined') {
      url = source.getUrl();
    }
    url += '?t=' + now;  //Prevents browser caching if retrieving a geoJSON file
    console.info('refreshGeoJson url: ' + url);
  this.getJson(url).when({
     ready: function(response) {
     var JSONResponse;
     try {
       JSONResponse = JSON.parse(response);
     } catch(err) {
       alert(err + ' - ' + url);
       return;
     }
     var format = new ol.format.GeoJSON();
     var features = format.readFeatures(JSONResponse, {
        featureProjection: 'EPSG:3857'
     });
       source.addFeatures(features);
      source.changed();
    }
  });
},
getJson: function(url) {
     var xhr = new XMLHttpRequest(),
     when = {},
     onload = function() {
     console.log(url + ' xhr.status: ' + xhr.status);
    if (xhr.status === 200) {
     console.log('getJson() xhr: ');
     console.dir(xhr);
     console.log('getJson() xhr.response: ');
     console.dir(xhr.response);
      when.ready.call(undefined, xhr.response);
    }
    if (xhr.status === 404) {
      console.log('map file not found! url: ' + url);
    }
     },
     onerror = function() {
       console.info('Cannot XHR ' + JSON.stringify(url));
     };
      xhr.open('GET', url, true);
      xhr.setRequestHeader('cache-control', 'no-store');
      xhr.onload = onload;
      xhr.onerror = onerror;
      xhr.send(null);
      return {
        when: function(obj) { when.ready = obj.ready; }
      };
  }
};

Threw in a lot of extras here because I'm not sure what your problem is with your code. The example above work great for me retrieving geoJSON files from the server that are periodically changed..It should work the same for you if calling a PHP script, just make sure that the script returns geoJSON data according to this spec: http://geojson.org/geojson-spec.html

Comments