Formatting the MousePosition control output in OpenLayers 3 - openlayers-3

I'm showing the mouse position in OpenLayers 3 with the following control
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: ol.coordinate.createStringXY(2),
projection: 'EPSG:4326',
undefinedHTML: ' '
});
But the result shows the mouse position as Lon,Lat rather than Lat,Lon.
Here's a jsfiddle example.
How can I reverse the order so that it's Lat,Lon?

What works for me to add a variety of controls incl Lat, Long is:
var controls = [
new ol.control.Attribution(),
new ol.control.MousePosition({
projection: 'EPSG:4326',
coordinateFormat: function(coordinate) {
return ol.coordinate.format(coordinate, '{y}, {x}', 4);
}
}),
new ol.control.ScaleLine(),
new ol.control.Zoom(),
new ol.control.ZoomSlider(),
new ol.control.ZoomToExtent(),
new ol.control.FullScreen()
];
(modified from the book of openlayers 3)

You change your coordinateFormat - "standard function" to a custom function:
var myFormat = function(dgts)
{
return (
function(coord1) {
var coord2 = [coord1[1], coord1[0]];
return ol.coordinate.toStringXY(coord2,dgts);
});
}
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: myFormat(2), // <--- change here
projection: 'EPSG:4326',
className: 'custom-mouse-position',
target: document.getElementById('mouse-position'),
undefinedHTML: ' '
});
see your modified fiddle

An alternative:
var template = 'LatLon: {y}, {x}';
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: function(coord) {return ol.coordinate.format(coord, template, 2);},
projection: 'EPSG:4326',
undefinedHTML: ' '
});

Also helpful to display in Degrees, Minutes, Seconds:
controls: ol.control.defaults().extend([
new ol.control.ScaleLine({
units: 'nautical'
}),
new ol.control.MousePosition({
coordinateFormat: function(coord) {
return ol.coordinate.toStringHDMS(coord);
},
projection: 'EPSG:4326',
className: 'custom-mouse-position',
target: document.getElementById('mouse-position'),
undefinedHTML: ' '
})
]),

Works in OpenLayers 3.7.0. Using proj4js to reproject coordinates to a different projection due to map view being in 'EGPS:3857':
var proj1 = proj4.defs('EPSG:4326');
var proj2 = proj4.defs('EPSG:3857');
var myFormat = function(digits) {
return (
function(originalCoordinates) {
var reprojectedCoordinates = proj4(proj2, proj1).forward(originalCoordinates);
var switchedCoordinates = [reprojectedCoordinates[1], reprojectedCoordinates[0]];
return ol.coordinate.toStringXY(switchedCoordinates, digits);
}
);
}
var mousePositionControl = new ol.control.MousePosition({
coordinateFormat: mojFormat(10),
projection: 'ESPG:4326',
undefinedHTML: '&nbsp'
});
// map.addControl(mousePositionControl); //equivalent to setMap
mousePositionControl.setMap(map);

Related

vectorSource.addFeatures with the parameter Array containing more than 10 features using openlayers 4.3.3

I have a map and I'd like to add features. The features are added correctly always at the end of the array. If there are more than 10 features added, the eleven one - is inserted anywhere.
draw.on('drawend', function(evt) {
var feature = evt.feature;
var anfang = ol.proj.transform(feature.getGeometry().getFirstCoordinate(), 'EPSG:3857', 'EPSG:4326');
var ende = ol.proj.transform(feature.getGeometry().getLastCoordinate(), 'EPSG:3857', 'EPSG:4326');
var url = '?lonlats='+anfang+'|'+ende+'&nogos=&profile=shortest&alternativeidx=0&format=geojson';
url = encodeURIComponent(url);
url = broutes+url;
var response = new XMLHttpRequest();
response.open('GET', url);
var onError = function() {
console.log('error');
}
response.onerror = onError;
response.onload = function() {
if (response.status == 200) {
var data = Ext.decode(response.responseText);
var arr = data.features[0].geometry.coordinates;
var arrayNew = [];
for (i=0; i<arr.length; i++){
var n = ol.proj.transform(arr[i], 'EPSG:4326', 'EPSG:3857');
arrayNew.push(n);
}
var data = new ol.geom.LineString( arrayNew );
//console.log(data);
var featureSnake = new ol.Feature({
geometry: data
});
snakeSource.addFeature( featureSnake );
var win = Ext.create('MyProject.view.window.Edit', {
record : featureSnake,
toDo: 'insert',
});
win.show();
} else {
onError();
}
}
I chanced my code like you told me (using version 4.3.3)
vectorSource = new ol.source.Vector({
useSpatialIndex: false
});
Now I have the following result vectorSource.getFeatures()
polygon1
polygon2
...
polygon15
polygon2
polygon3
...
polygon15
polygon1
I have all features twice.

Draw a circle again after vector export

After draw a circle in my map, I exported it with:
getAsJson : function() {
var geojson = new ol.format.GeoJSON();
var features = this.vectorSource.getFeatures();
var jsonData = geojson.writeFeatures( features,{
featureProjection: ol.proj.get('EPSG:3857'),
dataProjection: ol.proj.get('EPSG:4326')
});
return jsonData;
}
and the result was:
{"type":"FeatureCollection","features":[
{"type":"Feature","geometry":{
"type":"GeometryCollection","geometries":[]
},"properties":{
"circleCenter":[-4805776.093508227,-2600749.7153150304],"circleRadius":6658.801529937424
}
}]}
This is how I take the circle center and radius:
var draw = new ol.interaction.Draw({
source: vectorSource,
type: value, // Can be Circle,Point,Line,Polygon
// No Geometry Function when type is 'Circle' (omited code to simplify)
geometryFunction: geometryFunction,
maxPoints: maxPoints
});
draw.on('drawend', function( evt ){
var geometry = evt.feature.getGeometry();
// Check the type before try to get this! (omited code to simplify)
var center = geometry.getCenter();
var radius = geometry.getRadius();
evt.feature.set('circleCenter', center );
evt.feature.set('circleRadius', radius );
});
map.addInteraction( draw );
Now I'm trying to use this JSON to draw the same circle again, but it have no geometry and this is not working (work for all other geometries like point, polygong and line so the problem is it not the code):
var features = new ol.format.GeoJSON().readFeatures( jsonData, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
Just a note: I can see now the projection of center and radius was not changed. Must work on this too...
GeoJSON does not support Circle Geometry. So ol.format.GeoJSON() format doesnot convert JSON to ol.Feature object. So write a custom method which consumes the JSON data and creates a Circle geometry
var featuresJson = geoJson.features;
for ( var i=0; i<featuresJson.length; i++ ) {
var radius = featuresJson[i].properties.circleRadius;
var center = featuresJson[i].properties.circleCenter;
var feature = new ol.Feature(new ol.geom.Circle(center,radius);
vectorSource.addFeature(feature);
}
I think this can help me somehow... will see.
map.getViewport().addEventListener("dblclick", function(e) {
var coordinate = map.getEventCoordinate(e);
vectorSource.addFeature(new ol.Feature(new ol.geom.Circle(coordinate, dist)));
});

URL parameters for Openlayers 3 to zoom to location?

I have an OL3 web application and I am wondering if it is possible to include URL parameters (such as coordinate values) for which the application can parse and open up at a specific location?
For example http://mywebsiteaddress?x=longitudevalue&y=latitudevalue
Is this something that can be done using OL3?
Sure, see: http://openlayers.org/en/latest/examples/permalink.html for an example (uses an anchor instead of url parameters but the idea is the same).
I did not like the openlayers permalink example because it uses map units and not well-known latitudes and longitudes. Sp I wrote my own code to hand over latlon coordinates, zoom and set a marker to it:
function getURLParameter(name) {
return decodeURIComponent((new RegExp('[?|&]' + name + '=' + '([^&;]+?)(&|#|;|$)').exec(location.search) || [null, ''])[1].replace(/\+/g, '%20')) || null;
}
var mzoom=12;
var mlat = Number(getURLParameter('mlat'));
var mlon = Number(getURLParameter('mlon'));
var mzoom = Number(getURLParameter('zoom'));
var marker = 1
if (mlat == 0 || mlon == 0) {
mlat = 51.5; mlon = 7.0; mzoom=12; marker=0 //Default location
}
if (mzoom == 0 ) { mzoom=12 //Default zoom
}
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
closer.onclick = function() {
container.style.display = 'none';
closer.blur();
return false;
};
var overlayPopup = new ol.Overlay({
element: container
});
var expandedAttribution = new ol.control.Attribution({
collapsible: false
});
var map = new ol.Map({
controls: ol.control.defaults({attribution:false}).extend([
expandedAttribution
]),
target: document.getElementById('map'),
renderer: 'canvas',
overlays: [overlayPopup],
layers: layersList,
view: new ol.View({
center: ol.proj.fromLonLat([mlon, mlat]),
zoom: mzoom,
maxZoom: 18, minZoom: 8
})
});
if (marker == 1) {
var vectorLayer = new ol.layer.Vector({
source:new ol.source.Vector({
features: [new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([parseFloat(mlon), parseFloat(mlat)], 'EPSG:4326', 'EPSG:3857')),
})]
}),
style: new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 0.5],
anchorXUnits: "fraction",
anchorYUnits: "fraction",
src: "marker.svg"
})
})
});
map.addLayer(vectorLayer);
}
I used the output of the qgis2web plugin and modified the file qgis2web.js as above.

update position of geolocation marker in Openlayers 3

I wan't to have a marker on the map, which position is dynamically updated.
When I create the layer inside the function of the geolocation.on('change'-event it works, but the layer is added each time the geolocation changes. Therefore I wanted to create the layer outside that function and update only the position of the marker.
With the folowing code I get an 'TypeError: a is null'
var geolocation = new ol.Geolocation({
projection: map.getView().getProjection(),
tracking: true,
trackingOptions: {
enableHighAccuracy: true,
maximumAge: 2000
}
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: './_img/marker_.png'
})
});
var pos1 = geolocation.getPosition();
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(pos1)
});
var iconSource = new ol.source.Vector({
features: [iconFeature]
});
var iconLayer = new ol.layer.Vector({
source: iconSource,
style : iconStyle
});
map.addLayer(iconLayer);
geolocation.on('change', function() {
var pos_upd = geolocation.getPosition();
iconFeature.getGeometry().setCoordinates(pos_upd);
view.setCenter(pos_upd);
view.setZoom(18);
});
The browser Geolocation API, which is wrapped by ol.Geolocation, is asynchronous. After initiation, geolocation.getPosition() will always return undefined until the first change event.
The proper thing to do is to add the feature once you get a coordinate, in the change event handler.
You will need to use a conditional to determine if you should add ore update a feature.
I changed the code a bit, so that I created first an iconFeature, that wasn't already bound to a ol.geom.Point()-position. By this way there was no need to use geolocation.getPosition().
Later in the geolocation.on('change')-event I assigned the actual position to the geometry of the iconFeature.
Works like espected
// add an empty iconFeature to the source of the layer
var iconFeature = new ol.Feature();
var iconSource = new ol.source.Vector({
features: [iconFeature]
});
var iconLayer = new ol.layer.Vector({
source: iconSource,
style : iconStyle
});
map.addLayer(iconLayer);
// Update the position of the marker dynamically and zoom to position
geolocation.on('change', function() {
var pos = geolocation.getPosition();
iconFeature.setGeometry(new ol.geom.Point(pos));
view.setCenter(pos);
view.setZoom(18);
});

setCenter always ends near southpole

I'm new at OpenLayers3 and trying to build a simple form that centers my map to a given spot. The problem is that i'm always landing somwhere near the south-pole. here is my code:
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM
})
],
view: new ol.View({
center: [0,0],
zoom: 8
})
search.addEventListener("change", searchChanged);
function searchChanged()
{
var searchVal = encodeURIComponent(search.value);
var geocode = 'http://open.mapquestapi.com/nominatim/v1/search.php?key=KEY&format=json&q=' + searchVal;
$.getJSON(geocode, function(data)
{
if(!data)
{
return;
}
map.getView().setCenter(ol.proj.transform([data[0].lon, data[0].lat], 'EPSG:4326', 'EPSG:3857'));
}
);
}
Make sure your coordinate will not be treated as string:
ol.proj.transform([parseFloat(data[0].lon), parseFloat(data[0].lat]), 'EPSG:4326', 'EPSG:3857')
Better, debug it:
var coord = ol.proj.transform([parseFloat(data[0].lon), parseFloat(data[0].lat]), 'EPSG:4326', 'EPSG:3857');
console.info(coord);

Resources