Is it possible to make the symbolizer of a feature be a polygon?
Openlayers 3 has a ol.style.Circle and ol.style.RegularShape symbolizers for example. Is there something equivalent to a hypothetical ol.style.Polygon? Whereby you could make a dynamic symbolizer from multiple points?
The reason I want to do this is because I have markers on my map that are dynamically shaped depending on the data for that marker. It is possible to simply draw a ol.geom.Polygon at each point, but then they are not zoom independent. I want to have markers that are zoom independent, meaning that their size on the screen does not change when I zoom in or out.
And just to be clear, using raster images (for example in ol.style.Icon) is not possible. There are way too many markers in way too many shapes and colours in my project.
Yes, this is possible. ol.style.Style takes a geometry argument that you can use to overwrite the geometry that is used to render a feature.
var style = function(feature, resolution) {
// construct the polygon taking the resolution into account
var polygon = new ol.geom.Polygon(...);
return [
new ol.style.Style({
geometry: polygon,
stroke: ...
fill: ...
}),
];
};
Also see this question: Drawing a Speed Leader line in OpenLayers
Related
I construct three polygons in the google map using the help polygons in google Map API for developers site. They are look like one polygon inside an another polygon .When my page is loaded all three polygon are loaded.How can i get the inner polygon when the outer polygon is zoomed or clicked in google map?Image:polygon inside another polygon
Your polygon are just place in postion that appear as one is inside another
for google maps the way you place your polygon had not a topological meaning
A easy eay for avoid that a larger polygon is over a small one could be based on z-index
assignin z-index with higher value to the polygon over the others eg:
// the larger - at base
var polylgon1 = new google.maps.Polygon({
...
zIndex: 100
});
// the middle - at medium leve
var polylgon2 = new google.maps.Polygon({
...
zIndex: 200
});
// the smaller - at top leve
var polylgon3= new google.maps.Polygon({
...
zIndex: 300
});
I have several markers in a map, I want to color the area inside the maps of a different color. I've tried L.multiPolygon , L.polygon, L.rectangle, but nothing does but I want. I guess my only option is to calculate the boundings of all the markers and draw the polygon based on these points, right ?
Here the code
<c:forEach var="marker" items="${markers}" varStatus="rowIndex">
var marker${rowIndex.index} = L.marker([${marker.lat},${marker.lng}],{icon: yellowIcon,title: '${marker.title}'}).addTo(mymap)
.bindPopup( "${marker.HTMLMarkerPopupCode}").openPopup();
storeCoordinate(${marker.lat}, ${marker.lng}, polygonPoints);
</c:forEach>
var polygon = L.polygon(polygonPoints);
polygon.setStyle({fillColor: '#0000FF'});
polygon.setStyle({color: 'red'});
polygon.setStyle({weight:1});
polygon.setStyle({fillOpacity: 0.5});
mymap.addLayer(polygon);
I would like to achieve something similar to this picture:
You can use L.Polygon as well.
Just do something like this:
var polygon = L.polygon([
marker1,
marker2,
marker3,
], {
fillColor: '#f03' // My custom color here
}
).addTo(mymap);
Not sure exactly what you are trying to achieve?
You might be interested in computing the Convex Hull of your markers area.
In that case, you should be able to find some JavaScript implementations on the Internet. E.g., you can look at how it is done in Leaflet.markercluster plugin: https://github.com/Leaflet/Leaflet.markercluster/blob/master/src/MarkerCluster.QuickHull.js
EDIT:
As for creating Convex Hull, you could also use Turf, in particular turf.convex.
Turf also provides you with plenty other functionalities, including turf.concave.
I have a few geometries in map, the point is in polygon, I can highlight the polygon, but the point cannot be highlighted because of polygon enclose it. In new openlayers3 ol.featureoverlay has been removed, If have some ways to solve it, here is an example.
I updated that plunker to this fiddle to work against newer OL versions. It is not ready yet but perhaps it does what you need.
Basically I get a coefficient by comparing pointer coordinate with the coordinate of the closest feature. If this coefficient is short enough than add the feature to a ol.Collection.
To get the selected feature (for now, see https://github.com/openlayers/ol3/issues/4459) you can listen to collection changes:
collection.on('change:length', function(evt) {
if (collection.getLength() > 0) {
var feature = hoverInteraction.getFeatures().item(0);
// can be also
//var feature = collection.item(0);
}
});
Using the Highcharts example posted here how can you ensure that the Font Awesome icons will be positioned exactly in the middle of the data point like the native symbols/markers are? It gets called like this in the data series and uses the "plugin" that is found in that same Fiddle:
marker: {
symbol: 'text:\uf183' // fa-male
}
Using that example, if you toggle the series on/off a couple of times or zoom in/out the icons are no longer visually accurate, often displaying above the actual coordinate. In the image below you'd believe that data point had a value >50 based on where the icon is.
Their SVGRenderer example here doesn't seem to be effected.
It looks like problem with re-rendering icons later - height of the marker isn't considered. I suggest to change a bit logic for rendering icon:
var text = symbol.split(':')[1],
svgElem = this.text(text, x, y)
.attr({
translateY: h, // translate marker
translateX: -1
})
.css({
fontFamily: 'FontAwesome',
fontSize: h * 2
});
See demo: http://jsfiddle.net/2A7Zf/29/
If you want to use the markers XL-sized (i.e larger radius) for a custom chart (e.g. a Yes/No prevalence chart using the x and check icons, circle empty for the less prevalent one and circle filled for the more prevalent one and data labels showing counts/%s), then I'd recommend this tweak to center the symbols:
translateX: -w/2 + options.radius/4 - 3
I have layer with pictures, I want them to stay as they are and don't rotate with map when I call map.getView().setRotation(x) . There is option to disable rotation for map, but is it possible to disable rotation for one layer?
If your "layer with pictures" is a vector layer with icon images, the icons won't rotate by default. You can control rotation of icons by configuring the icon style with the rotateWithView option. The default is false. Make sure you don't have a style like this:
new ol.style.Style({
image: new ol.style.Icon({
src: 'data/image.png',
rotateWithView: true
})
});
If you do, just remove the rotateWithView: true line.
If your layer is a WMS layer, and your images are point styles, you may be lucky to have a WMS server that supports rotation. Then you can add a vendor option (ANGLE for GeoServer and MapServer) and update that whenever the view rotation changes:
map.getView().on('change:rotation', function() {
wmsLayer.getSource().updateParams({
ANGLE: map.getView().getRotation() / Math.PI * 180
});
The above snippet assumes that map is your ol.Map instance and wmsLayer is your ol.layer.Image instance with an ol.source.ImageWMS.
As far as I know, you can't disable rotation for one layer. As suggests the answer from #ahocevar the best practice should be to display your "pictures" in a separate vector layer and use the rotateWithView options in the style definition of this layer.