Zoom (center) map to markers in OpenLayer3 - javascript

I have problem with my OpenLayer3 map. When I add some markers to map I want to resize my map and change the zoom so that all markers were set on the screen.
My code looks like:
/** CREATE MARKERS **/
for (var i=0;i<1;i++){
var iconFeature = new ol.Feature({
geometry: new
ol.geom.Point(ol.proj.transform([Math.random()*360-180, Math.random()*180-90], 'EPSG:4326', 'EPSG:3857'))
});
vectorSource.addFeature(iconFeature);
var newBound = ol.Bounds();
newBound.extend([Math.random()*360-180, Math.random()*180-90]);
map.zoomToExtent(newBound);
}
/** MARKER STYLE **/
var iconStyle = [
new ol.style.Style({
image: new ol.style.Icon(/** #type {olx.style.IconOptions} */ ({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 1,
scale: 0.07,
src: 'marker.png'
}))
})
];
/** ADD LAYER VECTOR **/
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: iconStyle
});
/** INIT MAP **/
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
}),
vectorLayer
],
overlays: [overlay],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
Is there a way to zoom the map to markers?

You have some errors in your logic and in some OL references. First you should create an ol.Extent that contains all the markers. Then use the map's view to fit it in.
// create ten random markers
for (var i = 0; i < 10; i++) {
var point = new ol.geom.Point(ol.proj.transform([Math.random() * 50, Math.random() * 50], 'EPSG:4326', 'EPSG:3857'));
var iconFeature = new ol.Feature({
geometry: point
});
vectorSource.addFeature(iconFeature);
}
// make the map's view to zoom and pan enough to display all the points
map.getView().fit(vectorSource.getExtent(), map.getSize());
Here's a plunker:
https://plnkr.co/edit/KVL14vdOSqJBxZz44s3u?p=preview

Once your vector features has been drawn you may get the extent using:
vector.on('render',function(e){
var myextent = vector.getSource().getExtent();
})
And then you may zoom to this extent using:
map.getView().fit(myextent , map.getSize());
So if you are going to use the render event
vector.on('render',function(e){
map.getView().fit(vector.getSource().getExtent(), map.getSize());
})

Related

How to rotate markers individually in openlayers

I want to display on duty taxi positions using openlayers.
I have coordinates and heading of each taxi cab but when I'm trying to display them everything is okay with coordinates but headings aren't displaying properly. It's because I have the same style for every marker and adding them to the same vector layer.
I would like to show each vehicle with its own heading.
Any solutions for this issue will be appreciated.
My code:
var taxiMarker = new ol.style.Style({
image: new ol.style.Icon({
scale: 0.7, anchor: [0.5, 0.5],
src: 'uploads/taxiMarker.png'
})
});
var taxi_vector = new ol.layer.Vector({
source: new ol.source.Vector({
}),
style: [taxiMarker]
});
for(let i = 0; i < res.length; i++) {
let tCoords = res[i][0].split(',');
let heading = parseFloat(res[i][1]);
let marker = new ol.geom.Point(tCoords);
let featureMarker = new ol.Feature(marker);
taxiMarker.getImage().setRotation(heading);
taxi_vector.getSource().addFeature(featureMarker);
}

openlayers doesn't return the correct coordinates

I'm tring to get the coordinate of a location when I click on a marker. I can get latitude and longitude of a location but they aren't the same that I used to set them
For example if i use latitude:48.879882939225 longitude: 2.3558143608438 to set the marker for Paris, when I click on the same marker I receive latitude:49.00659123218202 longitude: 2.2758007269287077
I write this to set the map and its markers
let markers = getMarkers(data);
$('.content').html(
'<div id="map" class="map" style="height: 100%; width: 100%"></div>'
)
var map = new ol.Map({
target: 'map',
layers: [
new ol.layer.Tile({
source: new ol.source.OSM()
})
],
view: new ol.View({
center: ol.proj.fromLonLat([12.51, 41.89]),
zoom:6
})
});
map.on('singleclick', function(evt){
console.log(ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326'));
let lat = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326')[0];
let lng = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326')[1];
});
var features = [];
for (var i = 0; i < markers.length; i++) {
var item = markers[i];
var longitude = item.lng;
var latitude = item.lat;
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([longitude, latitude], 'EPSG:4326', 'EPSG:3857'))
});
var iconStyle = new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 1],
src: "http://cdn.mapmarker.io/api/v1/pin?text=P&size=50&hoffset=1"
}))
});
iconFeature.setStyle(iconStyle);
features.push(iconFeature);
}
var vectorSource = new ol.source.Vector({
features: features
});
var vectorLayer = new ol.layer.Vector({
source: vectorSource
});
map.addLayer(vectorLayer);
How can I get the correct coordinate ?
At zoom level 6 your marker will be more than 0.1 degrees wide. To get the coordinates of the marker use something like
map.on('singleclick', function(evt){
let features = map.getFeaturesAtPixel(evt.pixel);
if (features.length > 0) {
let coordinate = features[0].getGeometry().getCoordinates();
console.log(ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326'));
let lat = ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326')[0];
let lng = ol.proj.transform(coordinate, 'EPSG:3857', 'EPSG:4326')[1];
}
});

openlayers5: click event position not properly set on map

I'm trying to open a popup in a map with markers, getting the markers points from a list where latitude and longitude are given, and they are plotted correctly in the map.
Following https://openlayers.org/en/latest/examples/popup.html I added the code for opening popup, and this is my code:
var container = document.getElementById('popup');
var content = document.getElementById('popup-content');
var closer = document.getElementById('popup-closer');
var overlay = new ol.Overlay({
element: container,
autoPan: true,
autoPanAnimation: {
duration: 250
}
});
closer.onclick = function() {
overlay.setPosition(undefined);
closer.blur();
return false;
};
// create the map with the proper center
var map = new ol.Map({
controls: ol.control.defaults().extend(
[new ol.control.ScaleLine()]
),
view: new ol.View({
center: ol.proj.fromLonLat([center.long, center.lat]),
zoom: zoom
}),
overlays: [overlay],
layers: [new ol.layer.Tile(
{source: new ol.source.OSM()}
)
],
target: 'mapdiv',
keyboardEventTarget: document
}
);
// the style for the markers
var markerStyle = new ol.style.Style({
image: new ol.style.Icon(/** #type {module:ol/style/Icon~Options} */ ({
anchor: [0.5, 1],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
scale: 0.4,
src: 'img/ic_place_void_black_24dp_2x.png'
}))
});
for (i = 0; i < pointList.length; ++i) {
// add the marker
markersList[i] = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.fromLonLat([pointList[i].long, pointList[i].lat])),
namesList: pointList[i].mediaNameList
});
// apply the style to the marker
markersList[i].setStyle(markerStyle);
}
// generate the markers vector
var markers = new ol.source.Vector({
features: markersList
});
// generate the markers layer
var markerVectorLayer = new ol.layer.Vector({
source: markers,
});
// add the markers layer to the map
map.addLayer(markerVectorLayer);
/**
* Add a click handler to the map to render the popup.
*/
map.on('singleclick', function(evt) {
var clickedPosition = ol.proj.toLonLat(evt.coordinate);
console.log(clickedPosition);;
overlay.setPosition(ol.proj.fromLonLat(clickedPosition));
});
Now I'm stuck with a unexplicable behaviour; whenever I click, the popup is shown about one screen south-east, whatever zoom level of the map.
The coordinates of clickedPosition (I'm seeing them in the console) are the correct coordinates where I clicked, but the popup is shown in a wrong point, with a shift which is always the same in pixels.
What am I missing?
You can refer overlay positioning for showing features in any world.
follow the link

Multiple text labels along a linestring feature

Is it possible in OpenLayers 3 to create a text label which clones multiple times along a linestring feature, depending on a scale? Something like:
Here you can see, that when we change scale label "IX Corps Blvd" appears twice. How can we implement this?
You can achieve this with style function. My code sample is about making arrows to line string (slightly different case), but I have commented parts necessary to be changed (at least):
var raster = new ol.layer.Tile({
source: new ol.source.OSM()
});
var source = new ol.source.Vector();
var styleFunction = function(feature) {
var geometry = feature.getGeometry();
var styles = [
// linestring
new ol.style.Style({
stroke: new ol.style.Stroke({ // apply street style here
color: '#ffcc33',
width: 2
})
})
];
geometry.forEachSegment(function(start, end) {
var dx = end[0] - start[0];
var dy = end[1] - start[1];
var rotation = Math.atan2(dy, dx);
// arrows
styles.push(new ol.style.Style({
geometry: new ol.geom.Point(end),
image: new ol.style.Icon({ // Use here label, not icon.
src: 'http://openlayers.org/en/v3.17.1/examples/data/arrow.png',
anchor: [0.75, 0.5],
rotateWithView: false,
rotation: -rotation
})
}));
});
return styles;
};
var vector = new ol.layer.Vector({
source: source,
style: styleFunction
});
map.addInteraction(new ol.interaction.Draw({
source: source,
type: /** #type {ol.geom.GeometryType} */ ('LineString')
}));
Some more effort is needed to place titles in correct placements. I left this answer like this to serve a solid starting point for building your feature.
My source:
[1] http://openlayers.org/en/master/examples/line-arrows.html

How to rotate feature in openlayer 3?

Need to find a way to rotate a feature in openlayer3 while editing a feature.
Like in openlayer2 https://github.com/openlayers/openlayers/blob/master/examples/rotate-features.html
function rotateFeature(feature, angle, origin) {
feature.geometry.rotate(angle, origin);
feature.layer.drawFeature(feature);
}
Basically, all you have to do is to call the rotate function for you polygon, as shown in the code below:
var vectorSource = new ol.source.Vector({});
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://localhost/map_cache.php?z={z}&x={x}&y={y}'
})
}),
new ol.layer.Vector({
source: vectorSource
})
],
target: 'map',
view: new ol.View({
center: [0, 0],
zoom: 2
})
});
var marker = new ol.geom.Polygon([[
ol.proj.transform([-16,-22], 'EPSG:4326', 'EPSG:3857'),
ol.proj.transform([-44,-55], 'EPSG:4326', 'EPSG:3857'),
ol.proj.transform([-88,75], 'EPSG:4326', 'EPSG:3857')
]]);
var featureMarker = new ol.Feature({
name: 'Marker',
geometry: marker,
});
vectorSource.addFeature(featureMarker);
//Here is the code for rotating:
marker.rotate(Math.PI / 2.0, ol.proj.transform([-16,-22], 'EPSG:4326', 'EPSG:3857'));
//////////////////////////////////////////////////
map.on('click', function(evt)
{
var lonlat = ol.proj.transform(evt.coordinate, 'EPSG:3857', 'EPSG:4326');
console.log(lonlat);
});
I have created an example to rotate a feature:
Gist with code
The rotate feature is built in and turned on by default. You can rotate your map by pressing alt + shift and moving your mouse on the map. A button should appear to revert back the rotation back to 0 degrees.
http://openlayers.org/en/v3.9.0/apidoc/ol.control.html

Categories

Resources