OpenLayers 3, static tiles and XYZ coordinates - openlayers-3

The goal is to be able to zoom onto a high-res picture (11520x11520) that I have split into 256x256 squares. I took the large image and resized it to 80%, 60%, 40%, 20% and 8.89%. Then, for each of the images from 100% to 8.89%, I split them. It's to make an interactive video game map like this: http://www.ark-survival.net/en/dynamic-livemap/
I have tried this:
var map = new ol.Map({
target: 'ark_map',
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'images/map/{z}/map_{x}_{y}.png',
tileSize: 256,
maxZoom: 5
})
})
],
view: new ol.View({
center: [50, 50],
zoom: 5,
minZoom: 0
})
});
The result: I only see the top left corner on any zoom used. I've seen many examples and many questions, but combining static tiles and XYZ (on pixels) has never come up.
Here is the JS Fiddle.
How do you combine static tiles and XYZ coordinates based on a pixel system?

You have a very weird tile layout. What you describe maps to this set of resolutions:
var resolutions = [
45/4,
45/4/2*0.889,
45/4/4*0.889,
45/4/6*0.889,
45/4/8*0.889
];
With that, you can configure an ol.tilegrid.TileGrid:
new ol.tilegrid.TileGrid({
origin: [0, 11520],
resolutions: resolutions
})
See updated fiddle for the full code: https://jsfiddle.net/6moqu7q8/4/.

Related

OpenLayers - polygon boundary

I have my map object created like this:
new ol.Map({
...
view: new ol.View({
center: ol.proj.transform([15,49], 'EPSG:4326', 'EPSG:3857'),
zoom: 10,
minZoom: 7,
maxZoom: 18,
extent: ol.proj.transformExtent([11.8, 48.4, 19.2, 51.2], 'EPSG:4326', 'EPSG:3857')
})
});
Let's say I have a big polygon "A" ( see the picture below ). I have a smaller polygon "B", which sticks to one side of the polygon "A". An external system calculates polygon "B" coordinates using WGS coordinates - points "pt1" and "pt2" are positioned on connection between point "pt3" and "pt4". When I draw both polygon on my map, points "pt1" and "pt2" are not positioned on connection between point "pt3" and "pt4". I think, it's because OpenLayers connect points "pt3" and "pt4" by direct line. This connection is straight line on the globe, so on my map, it should be curve. And that's why, I think, the polygon "B" is not aligned with the polygon "A" although it is on the globe. Is there a way, how to fix this?

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>

384x384px tile to diplay at 384x384px on map (retina)

I serve TMS tile with in two flavours: 256px or 384px through renderd option scale=1.5.
With Openlayers 3, the only way I found to display these 384px tiles their original size is to transform the canvas context like this:
map.getViewport().getElementsByTagName('canvas')[0].getContext("2d").setTransform(1.5, 0, 0, 1.5, -w, -h);
I think it's not the proper way to go, so what would be the right one?
I played a bit with a special ol.tilegrid but with no success, see here:
https://jsfiddle.net/yvecai/owwc5bo8/8/
The output I aim for is on the right map.
There is no need to create a special tile grid or to apply any canvas scaling. All you need to do is set the tilePixelRatio of the source properly, which would be 1.5 in your case:
source: new ol.source.XYZ({
url: "http://www5.opensnowmap.org/base_snow_map_high_dpi/{z}/{x}/{y}.png?debug",
attributions: [/* ... */],
tilePixelRatio: 1.5
})
Also note that your expectation of the result is wrong. I updated your fiddle to compare the standard 256px tiles (on the right) with the hidpi 384px tiles (on the left). If you are viewing the fiddle on a hidpi display, you'll notice the difference. https://jsfiddle.net/owwc5bo8/9/
To summarize:
If you want to display high-dpi tiles on a mobile device with good sharpness, use tilePixelRatio :
https://jsfiddle.net/owwc5bo8/9/
If you want to display tiles with a size differnet than 256x256, create a proper ol.tilegrid, and a proper ol.view:
https://jsfiddle.net/owwc5bo8/12/
var extent = ol.proj.get('EPSG:3857').getExtent();
var tileSizePixels = 384;
var tileSizeMtrs = ol.extent.getWidth(extent) / 384;
var resolutions = [];
for (var i = -1; i <= 20; i++) {
resolutions[i] = tileSizeMtrs / (Math.pow(2, i));
}
var tileGrid = new ol.tilegrid.TileGrid({
extent: extent,
resolutions: resolutions,
tileSize: [384, 384]
});
var center = ol.proj.fromLonLat(
ol.proj.toLonLat([2, 49], 'EPSG:4326'),
'EPSG:3857');
var zoom = 5;
var view1 = new ol.View({
center: center,
zoom: zoom,
maxResolution: 40075016.68557849 / 384
});

OpenLayers 3 Convert Pixel Coordinates to Lat Long

I am new to OpenLayers and would appreciate any help I can get. How do you convert from pixel-based-coordinates to lat/lon? I'm using OL3 to view and draw features on a static image (6494 x 7687 jpg) using projection:
var projection = new ol.proj.Projection({
code: 'xkcd-image',
units: 'pixels',
extent: [0, 0, 6494, 7687]
});
At the end of a polygan draw I have this, which works fine:
draw.on('drawend', function (event) {
var coord = event.feature.getGeometry().getCoordinates();
console.log("YOU DREW A Polygon with coord="+coord);
});
Is there an easy way to convert the above pixel-based coordinates of the polygon to Lat/Lon coordinates? I do have the lat/lons of the four corners of the image.
Instead of specifying a custom pixel projection, configure your static image source with the imageExtent set to your corner coordinates, and set its projection to 'EPSG:4326':
new ol.source.ImageStatic({
// ...
imageExtent: [minLon, minLat, maxLon, maxLat],
projection: 'EPSG:4326'
})
If you want to show your image without being distorted, you have to configure your view with projection: 'EPSG:4326' as well. You'll then be working with geographic coordinates throughout.
Something similar is also shown in one of the official examples: http://openlayers.org/en/latest/examples/reprojection-image.html. The difference is that raster reprojection is used there, because image and view are in different projection.

set the projection of map in openlayers 3

I just want to convert the default projection of an Openlayers 3.9.0 from the default EPSG:3857 to EPSG:4326.
So I edited a basic code like
var layer = new ol.layer.Tile({
source: new ol.source.OSM()
});
var center = [-1.812, 52.443];
var proj = new ol.proj.Projection({
code: 'EPSG:4326',
units: 'm'
});
var view = new ol.View({
center: center,
zoom: 6,
projection:proj
});
var map = new ol.Map({
loadTilesWhileAnimating: false,
loadTilesWhileInteracting:false,
target: 'map',
layers: [layer],
view: view
});
If center is like var center = [-1.812, 52.443]; it does not go in the UK, as is should be, it goes in the center of the map.
If I do like var center = new ol.geom.Point(-1.812, 52.443); I see no map at all. What am I missing here?
Thanks
You have two issues:
You should not instantiate the EPSG:4326 projection by yourself, it's done by OpenLayers 3. You get the projection by calling ol.proj.get('EPSG:4326').
The ol.source.OSM source loads it's tiles from services that only support EPSG:3857. Since it's a XYZ-based tilesource, you might actually get the map working (if the tilecoords are valid), but the layer will not be positioned correctly and still be in EPSG:3857. You can use EPSG:4326 as the view projection, but then you have to use a background map that supports it.
A working demo can be found in the official examples.
OL does not currently transform tiles, but that is being worked.
https://github.com/openlayers/ol3/issues/3785

Resources