set the projection of map in openlayers 3 - 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

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>

How add feature in a different projection in Openlayers 3.5

I'm using Openlayer 3.5 and load an OSM map "EPSG:3857".
var extent = [116.826673, 4.854776, 126.748593, 18.697146];
var philiExtent = ol.extent.applyTransform(extent, ol.proj.getTransform("EPSG:4326", "EPSG:3857"));
var view = new ol.View({
center: ol.proj.transform([121.787633, 11.775961], 'EPSG:4326', 'EPSG:3857'),
zoom: 0,
extent: philiExtent,
resolutions: [2560, 1280, 640, 320, 160, 80, 40, 20, 10, 5, 2.5, 1.2, 0.6],
});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
target: 'map'
});
But my features from webService are in "EPSG:4326"
function showData(data) {
var format = new ol.format.WKT();
var feature;
$.each(data, function (i, link) {
feature = format.readFeature(link.geom);
wktTraffic.addFeature(feature);
})
console.log('done load map');
}
So how I make the map be on 4326 or the new feature be on 3857.
I prefer first option.
Check out the FAQ section: http://openlayers.org/en/master/doc/faq.html#how-do-i-change-the-projection-of-my-map-
How do I change the projection of my map?
There is a good chance that you want to change the default projection of OpenLayers to something more appropriate for your region or your specific data.
The projection of your map can be set through the view-property. Here are some examples:
// OpenLayers comes with support for the World Geodetic System 1984, EPSG:4326:
var map = new ol.Map({
view: new ol.View({
projection: 'EPSG:4326'
// other view properties like map center etc.
})
// other properties for your map like layers etc.
});
// To use other projections, you have to register the projection in OpenLayers:
//
// By default OpenLayers does not know about the EPSG:21781 (Swiss) projection.
// So we create a projection instance for EPSG:21781 and pass it to
// ol.proj.addProjection to make it available to the library for lookup by its
// code.
var swissProjection = new ol.proj.Projection({
code: 'EPSG:21781',
// The extent is used to determine zoom level 0. Recommended values for a
// projection's validity extent can be found at http://epsg.io/.
extent: [485869.5728, 76443.1884, 837076.5648, 299941.7864],
units: 'm'
});
ol.proj.addProjection(swissProjection);
// we can now use the projection:
var map = new ol.Map({
view: new ol.View({
projection: swissProjection
// other view properties like map center etc.
})
// other properties for your map like layers etc.
});
We recommend to lookup parameters of your projection (like the validity extent) over at epsg.io.
To reproject your features to EPSG:3857, you can set the options dataProjection and featureProjection when parsing the features from the WKT string. See also ol.format.WKT#readFeature
var format = new ol.format.WKT();
var feature;
$.each(data, function (i, link) {
feature = format.readFeature(link.geom, {
dataProjection: 'EPSG:4326',
featureProjection: 'EPSG:3857'
});
wktTraffic.addFeature(feature);
})

How to export a featureOverlay drawn on openlayers3 map (projection EPSG:3857) to a KML file projected to EPSG:4326

I am drawing polygons on a featureOverlay attached to openlayers3 map (projection EPSG:3857) as follows:
// create openlayers3 map
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
})
],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4
})
});
// create the featureOverlay to receive polygons
var featureOverlay = new ol.FeatureOverlay();
featureOverlay.setMap(map);
// create the tool to draw polygons
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
type: 'Polygon'
});
map.addInteraction(draw);
Until here, everything is ok! The idea is from oficial Draw features example. The next step is to export features drawn on the map to a KML file using projection EPSG:4326. I have tried to reach this task through the following code:
$('#download-button').click(function() {
// get the features drawn on the map
var features = featureOverlay.getFeatures().getArray();
// create an object to write features on a output KML file
var format = new ol.format.KML();
// write features to KML format using projection EPSG:4326
var kml = format.writeFeatures(features, 'EPSG:4326', 'EPSG:3857');
// Save KML node as KML file using FileSaver.js script
var str = (new XMLSerializer).serializeToString(kml);
var blob = new Blob([str], {type: "text/plain;charset=utf-8;"});
saveAs(blob, "NovaCamada.kml");
});
The main problem is KML file result always contains features with vertices on metrics units (I need degrees units!) even when shows the KML file on EPSG:4326.
The worst (and the purpose of my question) is that even when I change the piece of code that writes features to kml format to:
var kml = format.writeFeatures(features);
or:
var kml = format.writeFeatures(features, 'EPSG:3857', 'EPSG:4326');
the result is the same and nothing changes!
I expect ol.format.KML class converts the features from EPSG:3857 to EPSG:4326. Am I on the right way?
Do I need apply any reprojection on features before format it? Someone please could help me with this task?
Did I make myself clear?
P.S.: FileSaver.js
writeFeatures takes, as the 2nd argument, an object literal with two properties: dataProjection and featureProjection.
The KML format has a default dataProjection, EPSG:4326. This means you only need to specify the featureProjection in your case:
var result = kmlFormat.writeFeatures(features, {featureProjection: 'EPSG:3857'});
Unrelated note: we are changing the return type of writeFeatures in OpenLayers 3.1.0. writeFeatures will always return a string, for any format. This means you won't need to serialize the result of writeFeatures yourself with XMLSerializer.

OpenLayers 3 Map creation not centering

I have the following very simple code:
#map_center = [-32.951106, -60.669952]
#map = new ol.Map({
target: 'map-canvas',
layers: [new ol.layer.Tile({source: new ol.source.OSM()})],
view: new ol.View({
center: #map_center,
zoom: 5
})
})
It's in coffeescript, but you will get the idea. The problem is, the map does not center at all. It gets stuck in [0, 0]
Am I doing something wrong?
By default the view's projection is Web Mercator (EPSG:3857). This means the view center's coordinates should be expressed in that projection.
If you have latitudes and longitudes you can use the ol.proj.transform function to transform the latitudes longitudes to Web Mercator coordinates. For example:
var view = new ol.View({
zoom: 4,
center: ol.proj.transform([-60, -32], 'EPSG:4326', 'EPSG:3857')
});

how can i Restrict map to show only the selected country?

I am trying to make web map application with openlayers 3. I have a problem which i want to fix.
I am loading OSM layer as my base map of the application. But the problem with the OSM layer is that it shows whole world and I can pan my map all around the world.
I want my application to be fixed in certain part. I have map extent set but still it doesn't work.
I am using minZoom but it doesn't help.
Is there any other way to fix this prolem?
var centerpos = [84.2, 28.2];
var newpos = ol.proj.transform(centerpos,'EPSG:4326','EPSG:900913');
var baseLayerOSM = new ol.layer.Tile({
source: new ol.source.MapQuest({
layer: 'osm'
}),
isBaseLayer:true
});
var map = new ol.Map({
layers: [baseLayerOSM],
target: 'map',
controls: [new CustomControl()],
view: new ol.View({
extent:[80.05844110726194,26.34796712822462,88.2015218371264,30.44742963310623],
projection : 'EPSG:900913', // OSM projection
center : newpos,
minZoom:7,
zoom: 7
})
});
This is my code.
AJ
Basically your example should work, but I think you forgot to transform your extent to EPSG:900913 / EPSG:3857 as well.
var maxExtent = [80.05844110726194,26.34796712822462,88.2015218371264,30.44742963310623];
var map = new ol.Map({
layers: [baseLayerOSM],
target: 'map',
controls: [new CustomControl()],
view: new ol.View({
extent: ol.proj.transformExtent(maxExtent, 'EPSG:4326', 'EPSG:900913'),
projection : 'EPSG:900913', // OSM projection
center : newpos,
minZoom:7,
zoom: 7
})
});

Resources