OpenLayers 3 Convert Pixel Coordinates to Lat Long - openlayers-3

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.

Related

JSXGraph 0.99.7 union of curves

Because of the Moodle-STACK environment I am currently limited to JSXGraph 0.99.7. Is there a way to get the union of two curves given by coordinate vectors (polygons) in that version?
In 1.2.1 I do this using Clip.union(), which works fine in jsfiddle (not exactly a minimum working example) but not in STACK.
this.b = board.create('curve', JXG.Math.Clip.union( bneu, this.b, board),
{opacity: true, fillcolor:'lightgray', strokeWidth: normalStyle.strokeWidth,
strokeColor: normalStyle.strokeColor});
In 0.99.7 you have to do the union by hand. As long as the shapes are not overlapping this might be doable without too much work. Define a curve and set its
updataDataArray method:
c = board.create('curve', [[], []]);
c.updateDataArray = function() {
this.dataX = [];
this.dataY = [];
// copy now the coordinates of the polygons / curves into
// these arrays.
};
board.update();
You can access the coordinates of the polygon vertices by
polygon.vertices[i].X();
polygon.vertices[i].Y();
Attention: the last vertex is a copy of the first vertex, to make the polygon a closed curve.
The coordinates of a curve can be accessed by
curve.points[i].usrCoords[1]; // x-coordinate
curve.points[i].usrCoords[2]; // y-coordinate
The curve path can be interrupted by adding NaNs:
this.dataX.push(NaN);
this.dataY.push(NaN);
Hope that helps a little bit.

Hot can I get Circle geometry when using ol.interaction.Draw?

I'm drawing a Circle using ol.interaction.Draw.
this.draw = new ol.interaction.Draw({
source: this.vectorSource,
type: 'Circle'
});
this.draw.on('drawend', function( evt ){
// evt.feature have no geometry !!!
}
But How can I get the Circle geometry or anything that tell me how to draw same circle again?
OL3.0 you can create/edit Features, but not Circles... http://openlayers.org/en/v3.0.0/examples/draw-and-modify-features.html
OL3.5 you can create circles, but you can't edit .... http://openlayers.org/en/v3.5.0/examples/draw-features.html
OL_Latest you can't edit circles too: http://openlayers.org/en/latest/examples/draw-and-modify-features.html
I would be happy if I could reproduce the same circle later.
To get the center and radius of the circle feature drawn use the below code
this.draw.on('drawend', function( evt ){
var geometry = evt.feature.getGeometry();
var radius = geometry.getRadius();
var center = geometry.getCenter();
// .... your code
});
Since a circle is drawn the Geometry type would be of type ol.geom.Circle.
Using this Geometry object you can get the radius and center using getRadius() and getCenter() method. For more information about ol.geom.Circle go through this link.
http://openlayers.org/en/latest/apidoc/ol.geom.Circle.html
Almost there!
I'm now able to reproduce the "circle" by adding a geometry function to the draw intaraction.
var geometryFunction = ol.interaction.Draw.createRegularPolygon(90);
this.draw = new ol.interaction.Draw({
source: this.vectorSource,
type: 'Circle',
geometryFunction: geometryFunction,
});
this will generate geometries to the feature so I can store it and load it again later, but it is not a real circle, it is just composed by a 90 points polygon. so I can't edit it as a circle.
Some idea to get the radius of this geometry?
{"type":"Feature","geometry":{"type":"Polygon","coordinates":[[[-4804935.286197088,-2605909.2147242804],[-4804836.58537814,-2605831.0293000625],[-4804743.578928918,-2605746.149310523],[-4804656.719967494,-2605654.988282439],[-4804576.431661996,-2605557.9903431754],[-4804503.105168979,-2605455.6280569425],[-4804437.097727745,-2605348.4001225093],[-4804378.730919913,-2605236.8289435934],[-4804328.289102704,-2605121.458083764],[-4804286.018023582,-2605002.849618253],[-4804252.123622994,-2604881.581395582],[-4804226.771031053,-2604758.244222341],[-4804210.083763039,-2604633.4389848416],[-4804202.143117644,-2604507.773721655],[-4804202.987780893,-2604381.8606613115],[-4804212.613637674,-2604256.3132395847],[-4804230.973791778,-2604131.7431108924],[-4804257.978794381,-2604008.757168381],[-4804293.497079825,-2603887.954587199],[-4804337.355606593,-2603769.923905379],[-4804389.340700352,-2603655.2401565393],[-4804449.199094949,-2603544.462068375],[-4804516.639166305,-2603438.1293405974],[-4804591.332353169,-2603336.7600155673],[-4804672.914757844,-2603240.8479544464],[-4804760.988919055,-2603150.860431155],[-4804855.125748342,-2603067.2358558625],[-4804954.866620535,-2602990.3816390927],[-4805059.72560813,-2602920.672206864],[-4805169.19184868,-2602858.4471765244],[-4805282.732033666,-2602804.009702166],[-4805399.793006718,-2602757.6249976917],[-4805519.804458544,-2602719.5190447196],[-4805642.1817054115,-2602689.8774916218],[-4805766.328537677,-2602668.8447490656],[-4805891.640124453,-2602656.5232864586],[-4806017.505960285,-2602652.973132728],[-4806143.312839472,-2602658.211583866],[-4806268.447843544,-2602672.213118665],[-4806392.301327342,-2602694.909523055],[-4806514.269889141,-2602726.1902224356],[-4806633.759310369,-2602765.902820383],[-4806750.187450577,-2602813.8538411125],[-4806862.987083566,-2602869.809672071],[-4806971.608660867,-2602933.4977020747],[-4807075.522989073,-2603004.607649443],[-4807174.22380802,-2603082.793073661],[-4807267.230257243,-2603167.6730632004],[-4807354.089218667,-2603258.834091285],[-4807434.3775241645,-2603355.8320305482],[-4807507.704017182,-2603458.194316781],[-4807573.711458416,-2603565.4222512143],[-4807632.078266247,-2603676.99343013],[-4807682.520083456,-2603792.3642899594],[-4807724.791162578,-2603910.972755471],[-4807758.685563167,-2604032.240978142],[-4807784.038155108,-2604155.5781513825],[-4807800.725423122,-2604280.383388882],[-4807808.666068517,-2604406.0486520687],[-4807807.821405267,-2604531.961712412],[-4807798.195548487,-2604657.509134139],[-4807779.8353943825,-2604782.0792628312],[-4807752.83039178,-2604905.0652053426],[-4807717.312106336,-2605025.867786525],[-4807673.453579567,-2605143.8984683445],[-4807621.468485809,-2605258.5822171844],[-4807561.610091211,-2605369.3603053484],[-4807494.170019856,-2605475.693033126],[-4807419.4768329915,-2605577.0623581563],[-4807337.8944283165,-2605672.974419277],[-4807249.8202671055,-2605762.9619425684],[-4807155.683437819,-2605846.586517861],[-4807055.9425656255,-2605923.440734631],[-4806951.083578031,-2605993.1501668594],[-4806841.61733748,-2606055.375197199],[-4806728.077152494,-2606109.8126715575],[-4806611.016179442,-2606156.197376032],[-4806491.004727617,-2606194.303329004],[-4806368.627480749,-2606223.944882102],[-4806244.480648483,-2606244.977624658],[-4806119.169061707,-2606257.299087265],[-4805993.303225876,-2606260.8492409955],[-4805867.496346689,-2606255.610789858],[-4805742.361342616,-2606241.6092550587],[-4805618.507858818,-2606218.9128506687],[-4805496.539297019,-2606187.632151288],[-4805377.049875791,-2606147.9195533404],[-4805260.621735584,-2606099.968532611],[-4805147.822102594,-2606044.0127016525],[-4805039.200525293,-2605980.324671649],[-4804935.286197088,-2605909.2147242804]]]},"properties": null}
The Polygon's centroid can be the circle center I think.... the distance of this centroid to any point in the border can be the radius.... I don't know how to get this using JS.
To take the center:
this.draw.on('drawend', function( evt ){
var aa = evt.feature.getGeometry().getExtent();
var oo = ol.extent.getCenter(aa);
console.log( oo );
});
Now I must find a way to take the radius.

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

Openlayers 3: Why forEachFeatureAtPixel only return one feature

I create a text box where I can put the coordinates X,Y then I move the pin to the location and find which roads are there.
The pin move, but forEachFeatureAtPixel only return one feature instead of four. Also the feature I got doesn't have NOMBRE property
I'm using Openlayer 3 and my WMS server map.
As you can see in MapInfo (picture right side) I got all 4 features. Horizontal 2x "Calle 6" and Vertical 2x "Calle 1 Norte", and have NOMBRE property.
I'm using the same x, y from mapinfo where all 4 feature instersect.
new info: My layer is ol.layer.Tile instead of ol.layer.Vector, maybe that is the problem (checking)
wmsLyr09 = new ol.layer.Tile({
source: wmsSource
});
// move the pin to new position
geometry.translate(deltaX, deltaY);
var coordinate = geometry.getCoordinates();
var pixel = map.getPixelFromCoordinate(coordinate);
console.log('pixel: ' + pixel);
var allFeaturesAtPixel = [];
map.forEachFeatureAtPixel(pixel, function (feature) {
allFeaturesAtPixel.push(feature);
});
// feature[len]:1
console.log("feature[len]:" + allFeaturesAtPixel.length);
//feature[Name]: undefined
feature= allFeaturesAtPixel[0];
console.log("feature[Name]: " + feature.get('NOMBRE'));
In your map you probably have two layers, the WMS tile layer and the vector layer for the pin. So, OpenLayers doesn't know about the road features. If you are calling forEachFeatureAtPixel you are getting the only feature OpenLayers knows about: the pin.
What you want to do is make a WFS GetFeature request to get the features at the current pin position. Take a look at this example: http://openlayers.org/en/master/examples/getfeatureinfo-tile.html

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.

Resources