Stop loading a tile in OpenLayers 3 tileloadstart event - openlayers-3

I have a Tile layer using an XYZ source in OpenLayers 3 (version 3.13.1) with url property set to http://my.server/map/z{z}/row{y}/{z}_{x}_{y}.jpg. On my server Tile images in folders z2 to z8 are available. But OpenLayers also tries to fetch images from folder z1 which doesn't exist. The map displays correctly, but my browser's console shows a file not found error. Is there a way to stop loading obviously non-existent tiles in the tileloadstart event? My code is as follows:
function createTileLayer() {
var xyzSource = new ol.source.XYZ({
url: 'http://my.server/map/z{z}/row{y}/{z}_{x}_{y}.jpg'
});
xyzSource.on('tileloadstart', function(evt) {
if (evt.tile.tileCoord[0] == 1) {
// Stop loading the Tile ?!?!
}
});
return new ol.layer.Tile({
extent: _maxExtent,
preload: 1,
source: xyzSource
});
}
Any help is greatly appreciated.

The solution is to set up the source properly so it does not try to fetch images for zoom levels that you do not have available:
var xyzSource = new ol.source.XYZ({
url: 'http://my.server/map/z{z}/row{y}/{z}_{x}_{y}.jpg',
tileGrid: ol.tilegrid.createXYZ({
minZoom: 2,
maxZoom: 8
})
});

Related

How do I rotate the complete view in Openlayers?

I have a map I have created in QGIS 3.8. It is using OSM as the base map and I have a simple raster layer which is a georeferenced map.
QGIS has a useful plugin qgis2web that exports a complete set of files for Openlayers (and Leaflet).
Once in Openlayer format and viewed in a browser it is possible to rotate the complete view to rotate say the north-point 40 degrees (i.e. about 0.7 Radians) east by using Alt+Shift+Drag. You can see a demo of this working here: https://openlayers.org/en/latest/examples/rotation.html
What I am trying to do is to modify the generated code to show the map already rotated to the required angle. (This is because the georeferenced map does not have its north point at the top of the page.)
This is the layers.js code that I am trying to modify, presumably, I need a rotation: 0.7 but I cannot figure out where!
var wms_layers = [];
var lyr_OpenStreetMap_0 = new ol.layer.Tile({
'title': 'OpenStreetMap',
'type': 'base',
'opacity': 1.000000,
source: new ol.source.XYZ({
attributions: '',
url: 'http://a.tile.openstreetmap.org/{z}/{x}/{y}.png'
})
});var lyr_MyMap = new ol.layer.Image({
opacity: 1,
title: "King's Park",
source: new ol.source.ImageStatic({
url: "./layers/MyMap.png",
attributions: '',
projection: 'EPSG:3857',
alwaysInRange: true,
imageExtent: [-100073.533268, 6847294.601171, -93832.319311, 6852417.437192]
})
});
lyr_OpenStreetMap_0.setVisible(true);lyr_MyMap.setVisible(true);
var layersList = [lyr_OpenStreetMap_0,lyr_MyMap];
Thank you pavlos
Just adding one line at the end of the body of html file sorted it:
<script>map.getView().setRotation(Math.PI / 2.6 );</script>

OL3: Clustering Vector Features when can't determine Feature type

I have to load some Features in a Vector layer and have a style function.
var features = new ol.format.GeoJSON().readFeatures( geojsonStr, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
features: features,
});
/*
var clusterSource = new ol.source.Cluster({
distance: 15,
source: vectorSource
});
*/
var customStyleFunction = function( feature, resolution ) {
....
}
var vectorLayer = new ol.layer.Vector({
//source: clusterSource,
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
I don't know what kind of geometry I will get in geojsonStr. The problem is: When my collection is of type "Point" I can cluster it, but with any other types I can't see the Layer... How can I cluster Points and ignore Polygons and Lines? or let OL3 be clever enough to decide?
EDIT: I've read https://github.com/openlayers/openlayers/pull/4917
I would recommend you to create 2 different layers: One for clustering and a another one for a common vector layer.
To solve your problem, you can loop through the features and check the geometry type of each, and add it to an already existing source with the addFeature method:
for (var i = 0; i < geojsonFeatures.length; i++) {
if (geojsonFeatures[i].getGeometry().getType() === 'Point') {
clusterSource.addFeature(geojsonFeatures[i]);
} else {
vectorSource.addFeature(geojsonFeatures[i]);
}
}
I have created a jsfiddle which gets a couple of features from a GeoJSON object and add them to different sources depending on the geometry type. If you want to see more points in the cluster souce to make sure that it is working properly, you can use the commented lines as well.

How to prevent tile caching on ol.layer.Tile on data that is Live (WMS TileArcGISRest etc)

I've tried this
layer_info.ol_layer.getSource().setTileLoadFunction(function (img, src) {
img.getImage().src = src + "&seq=" + (new Date()).getTime();
});
but it only changes the params on the first call and all subsequent calls just use the cached tiles.
Strangely When Using this on an Image source like Mapguide it works wonderfully and requests a new image every time.
opLayer.getSource().setImageLoadFunction(function(img, src){
img.getImage().src = src + "&seq=" + (new Date()).getTime();
});
EDIT: Here is the full layer before it is pushed in.
layer_info.ol_layer = new ol.layer.Tile({
opacity: 1 - (conf_layer.transparency / 100),
style: layer_info.display_name,
source: new ol.source.TileWMS({
attributions: [new ol.Attribution({html: conf_layer.attribution})],
//cacheSize: 0,
crossOrigin: (conf_layer.crossOrigin != 'null') ? conf_layer.crossOrigin : null,
url: conf_layer.url,
projection: Model.Projection,
params: {'LAYERS': conf_layer.layers}
})
});
I've discovered that setting cacheSize zero makes it ignore caching, however that only works on layers that aren't being reprojected. I need this layer to be reprojected and always request new tiles when zoomed or panned. (background data is somewhat live, in my arcgis layer it is live)

How can I change ol.source.OSM tile url based on level (z value)

We supply tiles for levels 0-9. So when the user goes to a zoom level 10 or higher I want the URL to change back to the default values of Open Street Map.
I've tried this and it almost works. When level 10 or higher is selected I change the URL using the ol.source.OSM.setURLs() function. But in some cases - not all - the image is still set to our local URL. I'm assuming this is some kind of caching issue but not sure.
$scope.tilesource = new ol.source.OSM({
url : '/'+$scope.tileRoot+'/tiles/{z}/{x}/{y}.png',
wrapX : false
});
var raster = new ol.layer.Tile({
source : $scope.tilesource
});
$scope.tilesource.on('tileloadstart', function(arg) {
//console.log(arg.tile.src_);
if ($scope.tileLevelsSupported.search(arg.tile.tileCoord[0]) == -1) {
$scope.tilesource.setUrls(["https://a.tile.openstreetmap.org/{z}/{x}/{y}.png", "https://b.tile.openstreetmap.org/{z}/{x}/{y}.png", "https://c.tile.openstreetmap.org/{z}/{x}/{y}.png"]);
} else {
$scope.tilesource.setUrl('/'+$scope.tileRoot+'/tiles/{z}/{x}/{y}.png');
}
});
I've tried several methods on OSM and Tile but have had no luck. On those instances when the Tile URL is wrong I get the File Not Found 404 error (expected), but then it corrects itself and the tile gets loaded.
Thanks in advance.
Instead of changing the URL, you could use two different layers with the minResolution and maxResolution options:
var raster = new ol.layer.Tile({
source : $scope.tilesource,
minResolution: 200,
maxResolution: 10000000
});
var osmLayer = new ol.layer.Tile({
source: new ol.source.OSM(),
minResolution: 0,
maxResolution: 200
});
When you zoom in from level 9 to 10, the raster layer will become invisible and the osm layer will appear.

OL3: force loading of source

I have a layer with maxResolution set, such that the layer is displayed only when you zoom in at a certain level. My issue is that the layer source data is loaded only when zooming at that level. Is there a way to preload the vector source data?
var source = new ol.source.Vector({
url: '/mapsource/source.geojson',
format: new ol.format.GeoJSON()
});
// how do I force loading the source here, and not wait for the map to render at 80 zoom?
var layer = new ol.layer.Vector({
title: 'Test layer',
source: source,
style: my_style,
maxResolution: 80
});
You can load data over ajax and add to your source.
var source = new ol.source.Vector();
$.getJSON('/mapsource/source.geojson').done(function(data){
var features = (new ol.format.GeoJSON()).readFeatures(data);
source.addFeatures(features);
});

Resources