Raster Reprojection - request raster on different projection - openlayers-3

Im trying to make a WMS Request using OpenLayers3, with a OSM Base map (EPSG:3857).
The raster data on geoserver is on EPSG:32629.
Somehow(?!) my setup worked fine till recently.
The raster image correctly appeared on the map even with different projections.
After the update to 2.15.2 my layers are no longer displayed.
I traced the problem to a reprojection issue but couldn't quite figure it out.
my request is basically:
var untiled = new ol.layer.Image({
source: new ol.source.ImageWMS({
ratio: 1,
url: 'http://mygeo/geoserver/ws/wms',
params: {
'FORMAT': 'image/png',
'VERSION': '1.1.1',
"LAYERS": 'ws:myraster'
}
})
});
i've tried setting the 'SRS' parameter on the request (adding it to the params) but OL forces the 3857.
On the geoserver, the raster layer is configured with both native and declared SRS with 32629 and "Force Declared".
Any Thoughts that might help ?
Regards

Related

OpenLayers GeoJson reprojection

I hot stack with reprojection of GeoJson
I have GeoJson object loaded by ajax from server
Object has CRS set to EPSG:2180
I want to overlay it on OpenStreet Map that has CRS EPSG:3857
var buildingsFeatures = (new ol.format.GeoJSON()).readFeatures($buildings, {
dataProjection: 'EPSG:2180',
featureProjection: 'EPSG:3857'
});
$building is GeoJson FeatureCollection object and above code is as per OpenLayers documentation but coordinates are not changed.
I hit a wall with it :(
Things to do to make it working:
get proj4.js from https://github.com/proj4js/proj4js/releases
define EPSG:2180 either inside your code or in proj4-defs.js file as
proj4.defs([
[
'EPSG:2180',
'+proj=tmerc +lat_0=0 +lon_0=19 +k=0.9993 +x_0=500000 +y_0=-5300000 +ellps=GRS80 +units=m +no_defs'
]
]);
and that's all.

points not showing on map using a source.Vector loader function

I am having a problem showing a few points on the map where the geojson file is loaded from the server. The geojson file changes so I want a good way to refresh the map layer. To do this, I created the source.Vector (Version 3.17.1 of OpenLayers)
var locationSource = new ol.source.Vector({
format: new ol.format.GeoJSON({
defaultDataProjection :'EPSG:4326'
}),
loader: vectorLoader,
strategy: ol.loadingstrategy.all
});
function vectorLoader which executes a XHR call to retrieve the latest version of the geojson file. This has been simulated in the jsfiddle below
jsfiddle
The geojson file has valid json because the points on the map show if I use a source.Vector object which uses the url property instead of a loader like this:
var locationSource = new ol.source.Vector({
url: '/openlayers/location.geojson',
format: new ol.format.GeoJSON({
defaultDataProjection :'EPSG:4326'
})
});
I would use this but it is horrible about using cached versions of the geojson file when a new file is available. I want something that is more reliable which is why I'm trying to get this to work with a loader.
The jsfiddle link above has all the code and it seems to run fine but the the points never show up on the map after addFeatures, located here:
onSuccess: function(response) {
var format = new ol.format.GeoJSON();
var features = format.readFeatures(response, {
featureProjection: 'EPSG:4326'
});
source.addFeatures(features);
console.info(source.getFeatures());
map.updateSize();
source.changed();
You will see that no points show on the map for the data provided in the jsfiddle. I feel like I am missing something basic here but after finding many solutions, none work..I seems like the style function needs to be executed again after the 'addFeatures` load completes. This can be seen in the console log for the jsfiddle above.
Indeed this is just a minor issue you were missing.
First of all radius was not defined, this is probably pulled from a variable which you haven't copied to your fiddle.
The main issue though is the wrong projection used when you read your features featureProjection: 'EPSG:4326', it should be changed to featureProjection: 'EPSG:3857', since the default projection in an OpenLayers view is Web Mercator. It could also be the case, that you wanted to define the data projection explicitly while reading your GeoJSON, for this you should set dataProjection: 'EPSG:4326'.
A working example can be found in this fiddle: https://jsfiddle.net/9oukr51t/

Does OL3 support Vector Tiles on WebGL?

Does OpenLayers 3 support LineString and Polygon rendering on WebGL? I have set renderer to 'webgl' and tried to render a TopoJSON format Vector Tile but got the following error: "Uncaught TypeError: vectorSource.loadFeatures is not a function".
The following example from the OL3 web site only works if i remove the 'renderer' attribute from the map properties so the map is rendered using an HTML5 canvas:
var map = new ol.Map({
renderer: 'webgl',
layers: [
new ol.layer.VectorTile({
source: new ol.source.VectorTile({
attributions: [new ol.Attribution({
html: '© Mapbox ' +
'© ' +
'OpenStreetMap contributors'
})],
format: new ol.format.MVT(),
tileGrid: ol.tilegrid.createXYZ({maxZoom: 22}),
tilePixelRatio: 16,
url: 'http://{a-d}.tiles.mapbox.com/v4/mapbox.mapbox-streets-v6/' +
'{z}/{x}/{y}.vector.pbf?access_token=' + key
})
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
Only the canvas renderer supports vector tiles with ol.layer.VectorTile.
As already mentioned, only points are currently supported for WebGL rendering, but there certainly appears to be a desire to expand this out to lines and polygons. With the VectorTile support (granted canvas only) already being there, I couldn't imagine them not including full WebGL.
There was a code sprint last year where they did a proof of concept. There were a number of limitations, but it proved it was possible.
http://www.camptocamp.com/en/actualite/openlayers-3-towards-drawing-lines-and-polygons-with-webgl/
renderer ol.renderer.Type | Array.<ol.renderer.Type> | undefined
Renderer. By default, Canvas and WebGL renderers are tested for support in that order, and the first supported used. Specify a ol.renderer.Type here to use a specific renderer. Note that the Canvas renderer fully supports vector data, but WebGL can only render Point geometries.
http://openlayers.org/en/latest/apidoc/ol.Map.html

Setting maxFeatures on vector openlayer layer

So I use Openlayers 3.9.0 and I use a loader to get a vector layer from Geoserver. Here is the code that currently works.
var sourceVector = new ol.source.Vector({
format: new ol.format.GeoJSON(),
loader: function (extent) {
$.ajax('http://localhost:5550/geoserver/mymap/wfsservice=WFS&version=1.0.0&request=GetFeature&typeName=mymap:mylayer&outputFormat=application/json',
{type: 'GET'})
.done(
function(response) {
var geojsonFormat = new ol.format.GeoJSON({});
sourceVector.addFeatures(geojsonFormat.readFeatures(response,{dataProjection :projection,featureProjection : projection}));
})
.fail(function () {alert("BAD");});
},
strategy: new ol.loadingstrategy.tile(ol.tilegrid.createXYZ({maxZoom: 20}))
});
By setting a maxFeatures (...&maxFeatures=50&...) to my url I dont get all the features. Does this means that if I zoom in I will see more features and if I zoom out I will see less? Is maxFeatures related to the bbox and renders features according to the current map view and zoom levels? Or this isnt the concept? Because in my case , I always see a fixed number of features.
Thanks
The loader function of an ol.source.Vector is called with an extent, a resolution and a projection. The semantic expectation is that the loader function is responsible for loading all features within that extent.
ol.source.Vector maintains a history of all loaded extents, and will not try to load an extent that is within the already loaded extents.
So if you use the tile loading strategy at a low zoom level, and your maxFeatures causes some features to be ignored, zooming in will not make them appear (because loading that extent should already have been done be the parent tile load).
Because of this, using the WFS parameter maxFeatures with ol.source.Vector is generally a bad idea. If you really need to limit the number of features per request, consider limiting your layer to higher zoom levels or making several request for each loader call.
Additionally, your loader code does not use the extent parameter, making each request identical. Your loaders only responsibility is to load the features within the given extent. If you want to load all features independently of their location, use the all loading strategy.

OL3 and geoserver print module with OSM as background layer

I have an application built in OL3 and geoserver. I am using bootstrap and jQuery in my application.
I am trying to print the maps in pdf. I have OSM as a base layer in my application and other layers come from my local geoserver.
Now I have a situation where I need to print my map in pdf(with all the visible layers and OSM layer).
I have installed printing plugin in my geoserver and it works fine I have tested my printing module with the following codes:
http://localhost:8080/geoserver/pdf/print.pdf?spec={
"layout":"A4 portrait",
"srs":"EPSG:4326",
"units":"degrees",
"dpi":300,
"outputFilename": "map",
"mapTitle":"This is the map title",
"layers":[
{
"baseURL":"http://localhost:8080/geoserver/genesis/wms",
"opacity":0.5,
"singleTile":false,
"type":"WMS",
"layers":["District_Boundary", "DevelopmentRegions"],
"format":"image/png",
"styles":[]
}
],
"pages":[
{
"center":[84.25,28.1],
"mapTitle":"",
"comment":"",
"scale":4000000,
"rotation":0
}
] }
But the problem is how should I print my OSM layer in this?? I am not using Extjs in my application so I don't want to use that just for my printing functionality.
Can anyone suggest how should I do with just jQuery and bootstrap and plain javascript without Extjs??
Thanks.
You just need to add osm as another layer to your request payload like this
http://localhost:8080/geoserver/pdf/print.pdf?spec={
"layout":"A4 portrait",
"srs":"EPSG:4326",
"units":"degrees",
"dpi":300,
"outputFilename": "map",
"mapTitle":"This is the map title",
"layers":[
{
"baseURL":"http://a.tile.openstreetmap.org",
"maxExtent":[
//your extent of map in the correct projection
],
"tileSize":[
256,
256
],
"extension":"png",
"type":"OSM",
"opacity":1
},{
"baseURL":"http://localhost:8080/geoserver/genesis/wms",
"opacity":0.5,
"singleTile":false,
"type":"WMS",
"layers":["District_Boundary", "DevelopmentRegions"],
"format":"image/png",
"styles":[]
}
],
"pages":[
{
"center":[84.25,28.1],
"mapTitle":"",
"comment":"",
"scale":4000000,
"rotation":0
}
] }
You need to change the extent based on your need
Once you send the request Geoserver will populate the osm tiles and put it on the map
Be aware that you should put the osm layer before other layers in your json string otherwise it will be placed on top of other layers in the printed map.
Geoserver Print plugin works only on geoserver data. In your case, you should handle OSM data as a layer in your geoserver instance. There is no possibility to just "proxy" OSM tiles through geoserver, you have to import OSM data into your database. Please check this article:
http://blog.geoserver.org/2009/01/30/geoserver-and-openstreetmap/
When you are using OL3 (canvas support), you can consider browser-side printing. It is very simple to get image from canvas:
https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toDataURL
You can also generate PDF in JavaScript using:
https://github.com/MrRio/jsPDF

Resources