OpenLayers GeoJson reprojection - openlayers-3

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.

Related

Raster Reprojection - request raster on different projection

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

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/

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

Openlayers 3.6: Getting the center of the current map view

I'm trying to get the current center of an Openlayers map in lat/lon coordinates. I've got the following event handler setup:
this.map.on('pointermove', function (e) {
if (e.dragging) {
console.log(that.map.getView().getCenter());
}
});
This works, but I'm getting weird values. Here's an example:
[9318218.659044644, 3274618.6225819485]
Those are obviously not lat/lon values :) Do I need to transform this somehow? Thanks!
I'm not super familiar with openlayers but it sounds like the map is in different projection.
Check out the following on spherical_mercator, transform,
Open Layers projections
UPDATED
I've done a little more research, check out this example. Not sure what the projection your view is in. the map in this example is in ''EPSG:21781' if you go to a js console and enter map.getView().getCenter() you get [693230.7161150641, 179010.3389264635] but if you enter ol.proj.transform(map.getView().getCenter(), 'EPSG:21781', 'EPSG:4326') you get [8.658936030357363, 46.75575224283748] hope that helps.
For those who are working with angular.
Also, I would consider searching the projection of the map, instead of entering it manually.
import * as olProj from 'ol/proj'
import Map from 'ol/Map'
// ...
olProj.transform(
this.map.getView().getCenter(),
this.map.getView().getProjection(),
'EPSG:4326',
)
Update for OpenLayers 6 (assuming your map is called 'map') the following gives an array of [lon, lat] for the centre of your map's view.
ol.proj.toLonLat( map.getView().getCenter() )

Resources