Resizing OL3 features programmatically - openlayers-3

I have map with user drawn features. After the user custom enters a map scale, I need to be able to resize all the existing map features based on this scale.
What is the way to do this in OL 3? I've seen that in OL 2, there is a geometry.resize function.
Thanks.

You can accomplish this using a StyleFunction.
Look at the following example: http://openlayers.org/en/v3.4.0/examples/vector-layer.html
If you zoom the map, you'll see the labels appear at a certain resolution. This is controlled inside the style function. Here's a snippet:
var featureOverlay = new ol.FeatureOverlay({
map: map,
style: function(feature, resolution) {
// === SEE THIS NEXT LINE ===
var text = resolution < 5000 ? feature.get('name') : '';
if (!highlightStyleCache[text]) {
highlightStyleCache[text] = [new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#f00',
width: 1
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.1)'
}),
text: new ol.style.Text({
font: '12px Calibri,sans-serif',
text: text,
fill: new ol.style.Fill({
color: '#000'
}),
stroke: new ol.style.Stroke({
color: '#f00',
width: 3
})
})
})];
}
return highlightStyleCache[text];
}
});
So you could define the size you want the features to have for any resolution range. Note that the style property also applies to a ol.layer.Vector layer.

you can use API: map.updateSize().
Reference: http://openlayers.org/en/latest/apidoc/ol.Map.html#updateSize

Related

Openlayers 3 : How to change Geojson Icon src so it won't override other geojson types?

I'm able to change src of an icon when loading Point/MultiPoint Geojson, in this way:
that.geojsonLayers[index] = new that.openlayers.ol.layer.Vector({
source: new that.openlayers.ol.source.Vector({
format: new that.openlayers.ol.format.GeoJSON(),
url: url
}),
style: new that.openlayers.ol.style.Style({
image: new that.openlayers.ol.style.Icon({
src: 'http://mapmip.webiks.com/assets/Markers/marker-icon-blue.png'
})
})
but then I can't load other types of Geojson - Polygons are not being loaded at all, and Geometry Collection (which composed from icon and lines) is load only the icon.
What is the way to change the icon src so it won't override the other geojson type ?
You may use a style function to verify the geometry type you need to style. Setting an icon for styling a polygon is not correct.
Check this
1.Declare your style
var myMultiStyle = {
//here replace with your icon style
'Point': new ol.style.Style({
image: new ol.style.Circle({
fill: new ol.style.Fill({
color: 'rgba(255,255,0,0.4)'
}),
radius: 5,
stroke: new ol.style.Stroke({
color: '#ff0',
width: 1
})
})
}),
'LineString': new ol.style.Style({
stroke: new ol.style.Stroke({
color: '#f00',
width: 3
})
}),
'Polygon': new ol.style.Style({
fill: new ol.style.Fill({
color: 'rgba(0,255,255,0.5)'
}),
stroke: new ol.style.Stroke({
color: '#0ff',
width: 1
})
})
};
Create a style function
function myStyleFunction(feature,resolution){
return myMultiStyle[feature.getGeometry().getType()];
}
Asign the style function to your vector source
that.geojsonLayers[index] = new that.openlayers.ol.layer.Vector({
source: new that.openlayers.ol.source.Vector({
format: new that.openlayers.ol.format.GeoJSON(),
url: url
}),
style: myStyleFunction
})
Check this official example to see the result.

GeoJSON data not displayed on a vector layer

I'm trying to display a vector layer to show a set of geojson features.
When I try and add the layer though I get an error in the ol.js library "k.xd is not a function"
var geoData = {"type":"FeatureCollection",
"features":
[
{"type":"Feature","properties":{"Name":"","Description":""},"geometry":{"type":"Point","coordinates":[0.0,0.0]}},
{"type":"Feature","properties":{"Name":"1","Description":""},"geometry":{"type":"Point","coordinates":[11.50728,3.87471,0.0]}},
]
};
// vector layer
var vector = new ol.layer.Vector({
source: new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geoData)
}),
style: new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'red',
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.2)'
})
})
});
I've hacked together an example here http://jsfiddle.net/dxt95yt6/1/ that shows it not working but I can't figure out where this differs from the original tutorials.
Given style object is not correct for points and therefore features just don't show up. Try:
style: new ol.style.Style({
image: new ol.style.Circle({
radius: 8,
stroke: new ol.style.Stroke({
color: 'red',
width: 2
}),
fill: new ol.style.Fill({
color: 'rgba(255,0,0,0.2)'
})
})
})
Please note, in original code, there's another problem, too. Coordinates have to be transformed to EPSG:3857:
features: (new ol.format.GeoJSON()).readFeatures(
geoData,
{featureProjection: ol.proj.get('EPSG:3857')}
)
http://jsfiddle.net/zqx6644q/8/
Its always helpful to validate your geojson before using it. I can recommend geojsonlint which has alos an api to make sure your using a correct geojson.

How can I edit the selected text in Openlayers3?

I am doing an internship now and this is my first time to touch OL3.
I try to make a demo to draw and change text with markers.
But I find that I can only change all text of the marker instead of changing the selected one.
Here is a simple jsfiddle I made.
features: select.getFeatures()
This is not work for me I think.
So how can I do that?
You may change you style variable to a ol.FeatureStyleFunction() to get the label from a property stored at the feature.
var style = function () {
return [
new ol.style.Style({
image: new ol.style.Icon({
anchor: [0.5, 46],
anchorXUnits: 'fraction',
anchorYUnits: 'pixels',
opacity: 0.75,
src: '//openlayers.org/en/v3.8.2/examples/data/icon.png'
}),
text: new ol.style.Text({
font: '12px Calibri,sans-serif',
fill: new ol.style.Fill({ color: '#000' }),
stroke: new ol.style.Stroke({
color: '#fff', width: 2
}),
// get the text from the feature (`this` is the feature)
text: this.get('text')
})
})
];
};
And to update text, update this property:
var features = select.getFeatures();
features.forEach(function(feature){
feature.set('text', nameElement);
});
http://jsfiddle.net/jonataswalker/b44nxco8/

How to dynamically style Cluster layer without style function

How can I define the style of a cluster layer as an ol.style.Style object, and not as a function, in Openlayers 3?
I am using a library (ol3-google-maps) which only accepts ol.style.Style objects for styling. The official cluster example uses a style function to dynamically add the number of features in each cluster to it's icon:
style: function(feature, resolution) {
console.log(feature);
var size = feature.get('features').length;
var style = styleCache[size];
if (!style) {
style = [
new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
})
];
styleCache[size] = style;
}
return style;
}
ol3 style functions are great when the style depends on some property of the feature, such as the number of subfeatures in a cluster. There is no other way to use dynamic properties in the style.
You could use a common style for the cluster layer that does not depend on the cluster size (that does not show the number of features), such as this example.
However, you could also set a non-dynamic style for each feature, instead of each layer. That style could be calculated based on it's properties, giving you some of the possibilities of a style function.
This example is a modification of the official example that does not use a normal style function. Instead, it listens to the addfeature and changefeature events of the cluster source, and sets a style based on it's properties to the feature itself (see code below).
Not that this is not a general solution or replacement for style functions, although it should work fine for cluster sources. Notably, you lose the possibility to generate styles based on the resolution. Setting a style to a feature might not be desirable if the feature is used by other layers. You also have to consider performance issues.
var styleCache = {};
var styleFunctionIsChangingFeature = false
var styleFunction = function (evt) {
if (styleFunctionIsChangingFeature) {
return;
}
var feature = evt.feature;
var size = feature.get('features').length;
var style = styleCache[size];
if (!style) {
style = new ol.style.Style({
image: new ol.style.Circle({
radius: 10,
stroke: new ol.style.Stroke({
color: '#fff'
}),
fill: new ol.style.Fill({
color: '#3399CC'
})
}),
text: new ol.style.Text({
text: size.toString(),
fill: new ol.style.Fill({
color: '#fff'
})
})
});
styleCache[size] = style;
}
styleFunctionIsChangingFeature = true
feature.setStyle(style);
styleFunctionIsChangingFeature = false
};
clusterSource.on('addfeature', styleFunction);
clusterSource.on('changefeature', styleFunction);

How to indicate polygon vertices with small circles using OpenLayers?

I am using OpenLayers 3 and have more or less implemented everything in my requirements list, except one thing: I am asked to somehow make the polygon rendering indicate the polygon vertices with small circles.
In plain words, the desired polygon outline is not just a line - it is a line "adorned" with small circles in all the places where there is a vertex.
How can I do that in OL3? I searched in the ol.style.Style docs (that is, the style I pass via setStyle to the ol.layer.Vector containing my polygons), but didn't find anything relevant.
For reference, there is now an example showing how to display the vertices of a polygon with a custom style geometry:
http://openlayers.org/en/master/examples/polygon-styles.html
var styles = [
// style for the polygon
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
}),
// style for the vertices
new ol.style.Style({
image: new ol.style.Circle({
radius: 5,
fill: new ol.style.Fill({
color: 'orange'
})
}),
geometry: function(feature) {
// return the coordinates of the first ring of the polygon
var coordinates = feature.getGeometry().getCoordinates()[0];
return new ol.geom.MultiPoint(coordinates);
}
})
];
The kind OL3 devs have provided the answer on the GitHub issue list. You basically use a style's geometry function, that transforms the geometry before projecting it - and in that function, you add your vertices to a MultiPoint geometry. #tsauerwein went as far as creating a working fiddle - many thanks to him for his work.
var styleFunction = function() {
var image = new ol.style.Circle({
radius: 5,
fill: null,
stroke: new ol.style.Stroke({color: 'orange', width: 2})
});
return [
new ol.style.Style({
image: image,
geometry: function(feature) {
var coordinates = feature.getGeometry().getCoordinates()[0];
return new ol.geom.MultiPoint(coordinates);
}
}),
new ol.style.Style({
stroke: new ol.style.Stroke({
color: 'blue',
width: 3
}),
fill: new ol.style.Fill({
color: 'rgba(0, 0, 255, 0.1)'
})
})
];
};

Resources