OpenLayers text label overlap even with padding - gis

Ol docs state that Padding can be used on text labels for decluttering. ol/style/Text,
However my labels are still overlapping even when I indicate Padding.
Live example on codepen: https://codepen.io/sjvmarigerr/pen/oNNVMXb?editors=1010
Style Function:
function styleFunction (feature) {
return new ol.style.Style({
text: new ol.style.Text({
text: feature.get('PORT_NAME'),
padding: [3, 3, 3, 3],
font: "bold 15px sans-serif"
})
});};

Have you tried the declutter option??? If not give it a try, it might solve your problem.
To do so, replace your vector layer config from this:
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: styleFunction
});
To this:
var vectorLayer = new ol.layer.Vector({
source: vectorSource,
style: styleFunction,
declutter: true
});
Remember that declutter should hide label if overlapping and will show label when zoom level is enough for not overlapping.

Due to zoom level i really don't see a way it will not overlap, but to make it more visible you can try the example below.
https://codepen.io/gpproton/pen/gOOEjJj?editors=1010
function styleFunction (feature) {
return new ol.style.Style({
text: new ol.style.Text({
text: feature.get('PORT_NAME'),
padding: [3, 3, 3, 3],
font: "bold 11px sans-serif",
stroke: new ol.style.Stroke({
color: '#ffffff',
width: 1
}),
fill: new ol.style.Fill({
color: '#000'
})
})
});
};

Related

Use Fontawesome in Openlayers with different icon styles

I want to use different Fontawesome icon styles on my map. So far that's not a problem. But in my case the Icon: 'map-marker-alt' has only one unicode for 4 different styles (https://fontawesome.com/icons/map-marker-alt?style=regular). So the only style i could access is the regular style. Is it possible to reference to another style like the solid style ?
const markerStyle = new Style({
text: new Text({
text: '\uf3c5',
scale: 1.5,
textBaseline: 'bottom',
font: 'normal 16px "Font Awesome 5 Pro"',
fill: new Fill({ color: '#2196F3' }),
stroke: new Stroke({ color: 'black', width: 1 })
})
});
As per https://fontawesome.com/how-to-use/on-the-web/referencing-icons/basic-use, the font face weight is what is used to specify the style of icon to use. For the Regular style, the weight to use is 400 so your code needs to change to this:
const markerStyle = new Style({
text: new Text({
text: '\uf3c5',
scale: 1.5,
textBaseline: 'bottom',
font: '400 16px "Font Awesome 5 Pro"',
fill: new Fill({ color: '#2196F3' }),
stroke: new Stroke({ color: 'black', width: 1 })
})
});

How to remove x-axis index from the tooltip/label

How to remove this value from bars (1,) I am using PrimeFaces and jqPlot would like to leave only the second value when hovering over the bar.
I already tried to search various information on the internet but found nothing exclusively about this customization. By the image below I better illustrate which value I want to remove from my bars in the chart.
https://ibb.co/8jSk4zP
function skinBarImpurezasMinerais() {
this.cfg.shadow = false;
this.cfg.title = '';
//this.cfg.seriesColors = ['#e30910', '#FFC107'];
this.cfg.grid = {
background: '#ffffff',
borderColor: '#ffffff',
gridLineColor: '#F5F5F5',
shadow: false
};
this.cfg.axesDefaults = {
borderWidth: 0.1,
borderColor: 'bdbdbd',
rendererOptions: {
textColor: '#666F77'
}
};
this.cfg.seriesDefaults = {
shadow: false,
lineWidth: 1,
stackSeries: true,
renderer: $.jqplot.BarRenderer,
pointLabels: {show: true},
rendererOptions: {
varyBarColor: true,
barWidth: 50,
},
markerOptions: {
shadow: false,
size: 7,
style: 'circle'
}
}
}
Thanks!
I found the solution .. I had to add the block below
highlighter: { show: true,
showTooltip: true, // show a tooltip with data point values.
tooltipLocation: 'nw', // location of tooltip: n, ne, e, se, s, sw, w, nw.
tooltipAxes: 'y', // which axis values to display in the tooltip, x, y or both.
lineWidthAdjust: 2.5 // pixels to add to the size line stroking the data point marker
}

OpenLayers 3 Style Function for dynamic feature font setting

I am using php and mySQL to generate javascript for the vector layers and features. All is functionally working except I need to be able to control the feature text with zoom, which from my searches requires the use of a style function.
My issue is how/where do I create a function to set what is currently fixed as "font: 140/10 + 'px arial' " tied to the map zoom setting ?
My current design uses a php loop using the database to create the features with unique location and properties:
1) create the feature
2) set the style
3) push into the array iconFeatures0
var iconFeature = new ol.Feature({
geometry: new ol.geom.Point(ol.proj.transform([-0.163741,51.507847], 'EPSG:4326', 'EPSG:3857')),
p_title: 'Hyde Park Title',
p_line1: 'Hyde Park',
p_line2: 'Park information ...',
lat: 51.507847,
long: -0.163741,
});
iconFeature.setStyle(
new ol.style.Style({
image: new ol.style.Icon(({
anchor: [0.5, 1.0],
anchorXUnits: 'fraction',
anchorYUnits: 'fraction',
opacity: 0.85,
src: 'test_map/marker_0.png',
size: [52,64],
scale:0.5,
})),
text: new ol.style.Text({
text: 'Hyde Park',
offsetY: -37.5,
fill: new ol.style.Fill({
color: '#FF3300'
}),
font: 140/10 + 'px arial'
})
}),
);
iconFeatures0.push(iconFeature);
//On completion of the loop:
var vectorSource0 = new ol.source.Vector({
features: iconFeatures0
});
vectorLayer0 = new ol.layer.Vector({
source: vectorSource0
});
//setting up the map
var myOSMLayer = new ol.layer.Tile({
source: new ol.source.OSM()
});
// Create latitude and longitude and convert them to default projection
var myMapcentre = ol.proj.transform([-0.140180,51.501811], 'EPSG:4326', 'EPSG:3857'); //$long,$lat
var myMapView = new ol.View({
center: myMapcentre,
zoom: 14
})
var myMap = new ol.Map({
controls: ol.control.defaults().extend([
new ol.control.FullScreen()
]),
layers: [myOSMLayer, vectorLayer0],
loadTilesWhileInteracting: true,
target: document.getElementById('demoMap1'),
view: myMapView
});
Thanks in advance.
There are several ways to accomplish this, here is one of them.
First, it would be more efficient if you prepare the styles and simply apply them at different scale, so OpenLayers doesn't have to re-create the styles each time the zoom changes.
Then, instead of styling each feature individually, you would style the entire layer (you can still discriminate by feature "category" within the layer).
At last, you would benefit from the the option to consider the resolution when styling the layer:
vectorLayer0.setStyle(function(feature, resolution) {
return [new ol.style.Style({
text: new ol.style.Text({
font: resolution/1000+'px Calibri,sans-serif',
text: "test",
fill: fill
})
})];
});
You would remove the code iconFeature.setStyle( ... from your code and put the above code after having created vectorLayer0

Google Maps custom label x and y position

I am trying to adjust the x and y position of my custom label. Is this possible?
I haven't come across any documentation regarding this issue as of yet.
numberMarkerImg = {
url: '../images/mobile/map-marker.png',
size: new google.maps.Size(32, 38),
scaledSize: new google.maps.Size(32, 38)
};
// Letter markers
marker = new google.maps.Marker({
position : point,
map : map,
icon : numberMarkerImg,
draggable: false,
labelClass: "labels",
label: {
text: saved_label,
color: 'black',
fontSize: '12px',
x: '200',
y: '100'
}
});
"labelOrigin" ended up having to to be passed in since I am using a custom marker.
numberMarkerImg = {
url: '../images/mobile/map-marker.png',
size: new google.maps.Size(32, 38),
scaledSize: new google.maps.Size(32, 38),
labelOrigin: new google.maps.Point(9, 9)
};
Google Maps API v3 doesn't let you set MarkerLabel position, there're no x and y options.
The doc also says:
If you are using it with a custom marker, you can reposition it with the labelOrigin property in the Icon class.
As I can see you're using custom marker so maybe this is the way to go for you.
Alternatively, have a look at MarkerWithLabel. Is an extension to the default Marker object with more options available. Small demo: http://jsfiddle.net/LLd4drvx/239/.
Another option I don't see mentioned here. You can set a CSS class for the label, then set the position using CSS. First, add className to the label:
label: {
text: saved_label,
color: 'black',
fontSize: '12px',
className: 'marker-position',
}
And for the CSS:
.marker-position {
bottom: 6px;
left: 0;
position: relative;
}
For v3, you can use it like this. The blue pointer shown in the picture is an icon I use as svg. with the appropriate label position for this icon.
iconSVG = {
path: `M13.04,41.77c-0.11-1.29-0.35-3.2-0.99-5.42c-0.91-3.17-4.74-9.54-5.49-10.79c-3.64-6.1-5.46-9.21-5.45-12.07
c0.03-4.57,2.77-7.72,3.21-8.22c0.52-0.58,4.12-4.47,9.8-4.17c4.73,0.24,7.67,3.23,8.45,4.07c0.47,0.51,3.22,3.61,3.31,8.11
c0.06,3.01-1.89,6.26-5.78,12.77c-0.18,0.3-4.15,6.95-5.1,10.26c-0.64,2.24-0.89,4.17-1,5.48C13.68,41.78,13.36,41.78,13.04,41.77z
`,
fillColor: '#0084ff',
fillOpacity: 1,
strokeColor: '#ffffff',
strokeWeight: 1,
anchor: new google.maps.Point(14, 43),
labelOrigin: new google.maps.Point(13.5, 15)
};
This sequence is a faster way to find the right position. size, anchor, labelOrigin

KineticJS layer index when dragging

So my problem seems to be that a draggable object always is drawn over other objects.
Check out my fiddle.
and my code:
<!DOCTYPE HTML>
<html>
<head>
<style>
body {
margin: 0px;
padding: 0px;
}
canvas {
border: 1px solid #9C9898;
}
</style>
<script src="http://www.html5canvastutorials.com/libraries/kinetic-v4.3.1-beta.js"></script>
<script>
window.onload = function() {
var stage = new Kinetic.Stage({
container: 'container',
width: 578,
height: 200
});
var cableLayer = new Kinetic.Layer();
// build cable
var cable = new Kinetic.Line({
strokeWidth: 40,
stroke: 'green',
points: [{
x: stage.getWidth() / 2,
y: stage.getHeight() / 2
}, {
x: 100,
y: 100
}],
draggable: true
});
// build center
var c1 = new Kinetic.Circle({
radius: 60,
fill: 'black',
draggable: true,
x: stage.getWidth() / 2,
y: stage.getHeight() / 2
});
var c2 = new Kinetic.Circle({
x: 100,
y: 100,
radius: 60,
fill: 'black',
draggable: true,
});
//add everything to the layer
cableLayer.add(cable);
cableLayer.add(c1);
cableLayer.add(c2);
//add all to stage
stage.add(cableLayer);
//What to do when something is changed...
cable.on('dragmove', (function () {
c1.setPosition([cable.getPosition().x + cable.getPoints()[0].x, cable.getPosition().y + cable.getPoints()[0].y]);
c2.setPosition([cable.getPosition().x + cable.getPoints()[1].x, cable.getPosition().y + cable.getPoints()[1].y]);
cableLayer.draw();
}));
c1.on('dragstart', (function () {
c1.getLayer().afterDraw(function () {
cable.attrs.points[0].x = c1.getX()-cable.getX();
cable.attrs.points[0].y = c1.getY()-cable.getY();
cableLayer.draw();
});
}));
c2.on('dragstart', (function () {
c2.getLayer().afterDraw(function () {
cable.attrs.points[1].x = c2.getX()-cable.getX();
cable.attrs.points[1].y = c2.getY()-cable.getY();
cableLayer.draw();
});
}));
}
</script>
</head>
<body onmousedown="return false;">
<div id="container"></div>
</body>
</html>
So, I tried to set the index using
cable.on('dragmove', (function () {
c1.setPosition([cable.getPosition().x + cable.getPoints()[0].x, cable.getPosition().y + cable.getPoints()[0].y]);
c2.setPosition([cable.getPosition().x + cable.getPoints()[1].x, cable.getPosition().y + cable.getPoints()[1].y]);
c2.setIndex(1);
c1.setIndex(1);
cable.setIndex(2);
cableLayer.draw();
}));
Doesn't seem to work? Why is this? How do I get the circles to draw over the line in all cases? Mainly the case that you drag the line.
Is there somewhere I'm setting this differently somewhere else?
Thanks for your help
http://jsfiddle.net/nYHrg/3/
So the problem is that kineticjs (4.3.0) added a new 'drag' layer to improve dragging performance. Any time that you drag an object, it is put in the drag layer, and when you stop dragging, it is put back in it's own layer. This does not preserve your original z-index. Anytime you create a new object and you want to override this functionality you will have to set one of the attributes of the object as:
"dragOnTop: false"
see jsfiddle for exact implementation.