Openlayers 3 Offset RegularShape - openlayers-3

For clustered features I would like to make the following style in OL3:
A square, and on top of it another smaller square at the right-top corner. The bigger square would hold the symbol, and the smaller square would hold the number of the clustered features.
Similar to this
Is it possible to achieve this? In the API I've seen that ol.style.Icon and ol.style.Text has anchor and offset properties, but not RegularShape...

I have eventually overcome on this problem with using a single png image which included the square AND the smaller square, too, and overlayed the dynamic text on it, like this:
var clusterStyle = [new ol.style.Style({
image: new ol.style.Icon({
src: clustericon.png
}),
text: new ol.style.Text({
text: feature.get('features').length.size.toString(),
offsetY: -18,
offsetX: 18,
font: '12px Arial',
fill: new ol.style.Fill({
color: '#fff'
}),
scale: 1
}),
zIndex: 20
}), new ol.style.Style({
image: new ol.style.Icon({
src: 'overlayicon.png'
}),
zIndex: 21
})];
You can also insert an overlay image on it. Hope it helps you anyways

Related

OL3 / Geoserver: Vector tile labels gets cropped

I am trying to label vector tile point features but they always gets cropped at the tile border. I have tried (among many other things) using the renderBuffer option with no success.
I am using OL 3.19 and the vector tiles are served with Geoserver 2.10RC1 and I get the same errors in my production environment as well as editing an Boundless example (http://suite.opengeo.org/docs/latest/dataadmin/vectortiles/index.html).
I think maybe the tiles are served correctly from Geoserver and that Openlayers somehow render and then slices the tiles before presentation but I am kind of stuck on this.
Any ideas?
Screenshot of the way it looks
And the code snippet:
<script>
var style_simple = new ol.style.Style({
fill: new ol.style.Fill({
color: '#ADD8E6'
}),
stroke: new ol.style.Stroke({
color: '#880000',
width: 1
}),
text: new ol.style.Text({
text:'LOREMIPSUM'})
});
function simpleStyle(feature) {
return style_simple;
}
var map = new ol.Map({
target: 'map',
view: new ol.View({
center: [0,0],
zoom: 4
}),
layers: [new ol.layer.VectorTile({
renderBuffer:50, //doesn't matter
style:simpleStyle,
source: new ol.source.VectorTile({
tilePixelRatio: 1,
tileGrid: ol.tilegrid.createXYZ({maxZoom: 19}),
format: new ol.format.MVT(),
url: 'http://localhost:8080/geoserver/gwc/service/tms/1.0.0/testlayer#EPSG%3A3857#pbf/{z}/{x}/{-y}.pbf'
})
})]
});
</script>
I have the same problem with ol.layer.VectorTile and text labels.
All labels are sliced on the tile boundaries.
Full example: https://jsfiddle.net/rn3qc4ca/
I asked the openlayers developers for help: https://github.com/openlayers/ol3/issues/6275
-> This is not a bug in openlayers. The mapbox tiles really repeat the label points in neighbored tiles. If you use very big fonts the label will still be cropped.
My (unimplemented) idea is to place all labels into a separate ol.layer.Vector layer. As this type of layer is not sliced into tiles it is always printed completely.

OpenLayers 3 Resize a feature

I am using OpenLayers 3 and OpenStreetMap for my application.
I've managed to draw circle vectors on the map to draw markers, the problem I have is that the circles have always the same size when zooming in and out.
How can I change the size of the vectors according to the resolution ?
Here is my vector definition:
var dealerSource = new ol.source.Vector();
function dealerStyle(feature) {
var style = new ol.style.Style({
image: new ol.style.Circle({
radius: 6,
stroke: new ol.style.Stroke({
color: 'white',
width: 2
}),
anchor: [1.5, 1.5],
fill: new ol.style.Fill({
color: 'green'
})
})
});
return [style];
}
you can change the size of your circle depending on the zoom level ( if that's what you want to do )
var dealerSource = new ol.source.Vector();
function dealerStyle(feature) {
var style = new ol.style.Style({
image: new ol.style.Circle({
radius: map.getView().getZoom(),
stroke: new ol.style.Stroke({
color: 'white',
width: 2
}),
anchor: [1.5, 1.5],
fill: new ol.style.Fill({
color: 'green'
})
})
});
return [style];
}
getZoom() returns the zoom level of your map as a number you can either use it or do a transformation on it to suit the desired size of your circle.
Note that above the bigger the zoom level is the bigger your circle will be drawn, to do the inverse you can replace the value by:
yourMaxZoomLevel - map.getView().getZoom()
you can also use getResolution() it returns a number too

add image along the lineString in Openlayers3

I would like to place images on a line. For example, instead of a dotted or dashed line, I could include a symbol of a ship or a character (e.g. |) repeated along the line.
Here is code:
lineStyle = new ol.style.Style({
image: new ol.style.Icon(({
opacity: 1,
size:20,
src: './icon.png'
})),
stroke: new ol.style.Stroke({
color: 'black',
width: 5,
lineDash: [10]
})
});
I want to get a result like this:
Here is my example, but it cannot show the image along with line. http://jsfiddle.net/Wenhua1224/jguxq4j0/

set different style for lines in vector openlayers layer

So, I use openlayers 3.9.0 and I have a vector layer that contains LineStrings, Polygons and Points.
By default LineStrings look like black lines, with litte stroke. I try to make them a bit thicker and their color have to be visible, so they not blend in, when many features are rendered.
This is my style
var stroke = new ol.style.Stroke({
color: 'rgba(0,0,0,0.4)',
lineCap: "butt",
lineJoin: "bevel",
width:1
});
function styleFunction(feature, resolution) {
var color = feature.get('color');
var name = feature.get('name');
var geom = feature.getGeometry().getType();
var fill = new ol.style.Fill({
color: color
});
//this does not work
if (geom == 'LineString') {
stroke.width=42;
}
var circle = new ol.style.Circle({
radius: 6,
fill: fill,
stroke: stroke,
color:color
});
var text= new ol.style.Text({
font: '20px Verdana',
text: name,
fill: new ol.style.Fill({
color: [64, 64, 64, 0.75]
})
})
var cStyle = new ol.style.Style({
fill: fill,
stroke: stroke,
image : circle,
text : text
});
return [cStyle];
}
I can not make this work. Any tips?
Thanks
OpenLayers 3 styles are immutable, they can not be changed.
Instead of trying to modify the width of the Stroke, create a new one with the options you want.

What's "an array of ol.style.Style" good for?

A style of an ol.layer.Vector can be set as ol.style.Style, a style function or an array of ol.style.Style. What's the array for and what does it do -- compared to just passing an ol.style.Style object?
I cannot find any information on this, neither in the official API docs nor in the tutorials.
If you look at the draw features example, when drawing lines, they are displayed in blue with a white border/outline.
These is achieved by styling the line twice, first with a large white line, then a thin blue line above.
There are 2 styles for the same geometry. It can’t be done with a single ol.style.Style, so to achieve this you need to pass an array of 2 styles: see the source for this.
Because I think this is still relevant and the edit queue is full for the approved answer, I'm posting this with the links updated and with code examples.
The most common way to see the array of styles in action is when drawing features since this is default style in Openlayers. For the line to appear blue with a white border it has to have two styles since it can't be done with a single Style. Openlayers does this by default like this:
styles['LineString'] = [
new Style({
stroke: new Stroke({
color: white,
width: width + 2,
}),
}),
new Style({
stroke: new Stroke({
color: blue,
width: width,
}),
}),
];
source
To expand on how usefull this feature could be you could check the custom polygons example. To have the vertices highlighted, they use two styles, one for the vertices and another for the polygon contour itself. Relevant piece of code:
const styles = [
new Style({
stroke: new Stroke({
color: 'blue',
width: 3,
}),
fill: new Fill({
color: 'rgba(0, 0, 255, 0.1)',
}),
}),
new Style({
image: new CircleStyle({
radius: 5,
fill: new Fill({
color: 'orange',
}),
}),
geometry: function (feature) {
// return the coordinates of the first ring of the polygon
const coordinates = feature.getGeometry().getCoordinates()[0];
return new MultiPoint(coordinates);
},
}),
];

Resources