I am using OpenLayers to make a map from json data. I have to load it once already (with PHP) to check timestamps and verify information. At that point, I'd rather output a javascript variable and just have OL use that. I can't seem anything in the docs to accomplish this.
Ideally, I'd just change 'url': 'latest.json' to something like 'local': json_variable
var pointsSource = new ol.source.GeoJSON({
'projection': map.getView().getProjection(),
'url': 'latest.json'
});
var pointsLayer = new ol.layer.Vector({
source: pointsSource,
style: new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 40],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
src: 'openlayers/marker-icon.png',
}))
})
});
map.addLayer(pointsLayer);
You can pass in your geojson data via the param 'object'.
The OL3 src is quite readable and often it is faster to read this to work out what to do than it is to hunt through the docs! I'm assuming you're using ol3.4 or earlier; here is the 3.2 src code for geojson:
https://github.com/openlayers/ol3/blob/v3.2.0/src/ol/source/geojsonsource.js
You can see it takes an object param, which is expecting a JS object, which is the result of JSON.parse("...your geojson string here...")
So something like:
var geojson_cache = "<?php output from PHP here ?>"
var geojson_object = JSON.parse(geojson_cache)
var pointsSource = new ol.source.GeoJSON({
'projection': map.getView().getProjection(),
object: geojson_object
});
should do what you need.
Also FYI -- I mention OL3.4 or earlier above - the reason is that this class no longer exists in 3.5. You can see from that src file above that this class isn't much more than a wrapper around StaticVector with a ol.format.GeoJSON formatter attached. This has been refactored and will be replaced by ol.source.Vector and you provide the ol.format.GeoJSON formatter. Have a read of 'New Vector API' in these notes:
https://github.com/openlayers/ol3/releases/tag/v3.5.0
Related
I'm using OpenLayers (v6.3.1) with ol-ext extensions (to handle animated clustering) on a simple html/javascript/jquery project.
I succeeded displaying data from a geojson with a vector source passed to cluster source then added to a layer.
My goal is now to add/remove filters (by user interaction) to the geojson fields displayed on the map.
The code of vector/cluster sources and the cluster layer :
const clusterSource = new ol.source.Cluster({
distance: 40,
source: new ol.source.Vector({
url: `${URL_PATH}`,
format: new ol.format.GeoJSON(),
})
});
const clusterLayer = new ol.layer.AnimatedCluster({
name: 'Cluster',
source: clusterSource,
animationDuration: $("#animatecluster").prop('checked') ? 700 : 0,
// Cluster style
style: getStyle
});
I'm stuck on the filtering part : should I filter the features array and replace the source of my layer? Or is there a easier way to do it with Openlayers?
Thanks for any help!
Using the latest version of Openlayers, 4.3.1, i set a vector source as follows:
this.vectorSource = new ol.source.Vector({
url: `../assets/data/file.json`,
format: new ol.format.TopoJSON()
});
this.vector = new ol.layer.Vector({
source: this.vectorSource,
style: this.style
});
But the file, in some cases, needed a previous treatement through other function.
How i can load the file.json, treat him and use in ol.source.vector?
I trying with a response ajax too, where dataSource variable is a response from ajax call to same URL in the first example ../assets/data/file.json
vectorSource = new ol.source.Vector({
features: (new ol.format.TopoJSON()).readFeatures(dataSource)
});
This can be done quite easily. Configure the ol.source.Vector without a URL. Instead, you can load your json yourself and turn it into an object with
var json = JSON.parse(dataSource);
Then modify the JSON object, and finally call
var features = new ol.format.TopoJSON().readFeatures(dataSource,
{featureProjection: view.getProjection()});
vectorSource.addFeatures(features);
Note the featureProjection option, which is required unless your view has the same projection as your data source.
This issue is more a javascript problem than an OpenLayer one. I guess...
The sample just work fine with my own WMS server : http://openlayers.org/en/v3.0.0/examples/graticule.html
In my project, the 'map' object is set in the map.js file, loaded in the index.html before the graticule.js file. It displays the map, as expected.
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map',
});
Now my very simple code in graticule.js
"use Strict";
var graticule = new ol.Graticule();
graticule.setMap(map);
map.getViewPort().style.cursor = 'crosshair';
Ok now the fun part :
I can see the crosshair (SO the map object is ok!), but the setMap(map) just throw an error "TypeError : a is null" in the debug console.
I'm not a Javascript expert so it can be a relatively dumb reason.
Please, help, I'm stuck.
Problem solved.
I used ol.proj.Projection in the view property, but I need to use directly the string projection code :
var view = new ol.View({
center: center,
zoom: 6,
projection: 'EPSG:4326'
});
After three days of vainly looking everywhere (learning books OpenLayers3, Javascript and Internet) for a solution I put my question here.
The problem is that I can't get relative url's working in OpenLayers3. Here I give an example:
I have a OpenLayersscript in a map/directory called sandbox.
The relative url's in the HTML part of this script are working, including the relative url in javascript to ol.js.
The problem is that the relative url in the Javascript part of the script don't work. Only when the targetfile (nutsv9_lea.geojson) is in a map/directory underlying the map/directory containing the OpenLayersscript itself, it works, but only in Firefox and not in Google Chrome and InternetExplorer.
The map sandbox (containing this OpenLayersfile) is located in the maps/directories structure: C:/ol3_samples/sandbox
The targetfile (nutsv9_lea.geojson) is located in the maps/directories structure: C:/ol3_samples/assets/data/nutsv9_lea.geojson
The relative url I use is: url: '../assets/data/nutsv9_lea.geojson'
The only working solution (as mentioned above only in Firefox) is the relative url targeting to a underlying map/directory called 'data' containing the target file: url: 'data/nutsv9_lea.geojson' in the map/directory structure: C:/ol3_samples/sandbox/data/nutsv9_lea.geojson
What am I doing wrong or am I overlooking?
<script>
var vectorSource = new ol.source.GeoJSON({
projection: 'EPSG:3857',
//not working relative url:
// url: '../assets/data/nutsv9_lea.geojson'
//working url (with the targetfile in a directory below the directory containing this script) but only working in Firefox and not working in Chrome and InternetExplorer
url: 'data/nutsv9_lea.geojson'
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
var center = ol.proj.transform([5.231819, 52.091852], 'EPSG:4326', 'EPSG:3857');
var view = new ol.View({
center: center,
zoom: 5
});
var map = new ol.Map({
target: 'map',
layers: [vectorLayer],
view: view
});
</script>
I'm one of the authors of the book where this extract comes from. You need to run a local server (where files are served via http:// and not file://).
You just need to look at p 117.
It tells you can run (as long as you have Python)
python -m SimpleHTTPServer
or in case you got the samples from Packt website, run (if you have node)
node index.js
For both NodeJS and Python, you have install instructions (pages 417 & 418),
For Python and people who do not own the book, go to http://docs.python-guide.org/en/latest/starting/installation/
I'm trying to load geojson data with openlayers 3. It's a lot of date, so I want to transfer just the data needed. I archived this by passing resulution and extent of the current view to the webservice. This is my code so far:
var vectorSource = new ol.source.ServerVector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
var url = 'data.json?e=' + extent.join(',') + '&r=' + resolution;
$.ajax({
url: url,
success: function(data) {
vectorSource.addFeatures(vectorSource.readFeatures(data));
}
});
},
projection: 'EPSG:3857',
strategy: ol.loadingstrategy.bbox
});
var vector = new ol.layer.Vector({
source: vectorSource
});
var map = new ol.Map({
layers: [vector],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 0
})
});
But my code only calls the webservice once. Which loading strategy do I have to use to call the webservice everytime the extent (and/or the resulution) changes?
ol.source.ServerVector does not know that you return different results for different resolutions. It remembers the areas loaded and does not load an area if it "knows" that its features are already loaded.
Your example initially loads the whole world (zoom=0), therefore no additional load is needed ever. Replace zoom=0 by lets say zoom=10: now a zoom out will trigger a load, because the larger area is not already known, while a zoom in will not trigger a load.
To reload on every change of resolution, you have to clear the memory.
Add after the definition of your map:
map.getView().on('change:resolution', function(evt){
alert ('resolution changed');
vectorSource.clear();
});
This code clears the memory each time the resolution changes and forces a load to be triggered.