How to highlight the subdivision's outline programmatically in a GeoJson layer? - openlayers-3

There is a GeoJson sourced layer in my map,and subdivision's outline will be highlighted when mouse overring it due to corresponded event registered.
Question is how to highlight a subdivision's outline programmatically(not by mouse overring)?

You have to find programmatically the feature (subdivision's outline) that you want highlight.
I suppose you have already defined a source, vector layer and overlay (it is a layer that contains only the features which are highlighted) in your code:
source = new ol.source.Vector({
url: '[your url]',
format: new ol.format.GeoJSON()
...........
layer = new ol.layer.Vector({
source: source
.....................
overlay = new ol.layer.Vector({
.........................
First it is necessary to find all the features
var _features = source.getFeatures();
Then you need a name or id to find the feature:
for (i = 0; i < _features.length; i++) {
if (_features[i].get('name') === name) {
_feature = _features[i];
break;
}
}
The you will add the feature to the overlay vector layer:
overlay.getSource().addFeature(_feature);

Related

OL3: Clustering Vector Features when can't determine Feature type

I have to load some Features in a Vector layer and have a style function.
var features = new ol.format.GeoJSON().readFeatures( geojsonStr, {
featureProjection: 'EPSG:3857'
});
var vectorSource = new ol.source.Vector({
features: features,
});
/*
var clusterSource = new ol.source.Cluster({
distance: 15,
source: vectorSource
});
*/
var customStyleFunction = function( feature, resolution ) {
....
}
var vectorLayer = new ol.layer.Vector({
//source: clusterSource,
source: vectorSource,
style : customStyleFunction
});
map.addLayer( vectorLayer );
I don't know what kind of geometry I will get in geojsonStr. The problem is: When my collection is of type "Point" I can cluster it, but with any other types I can't see the Layer... How can I cluster Points and ignore Polygons and Lines? or let OL3 be clever enough to decide?
EDIT: I've read https://github.com/openlayers/openlayers/pull/4917
I would recommend you to create 2 different layers: One for clustering and a another one for a common vector layer.
To solve your problem, you can loop through the features and check the geometry type of each, and add it to an already existing source with the addFeature method:
for (var i = 0; i < geojsonFeatures.length; i++) {
if (geojsonFeatures[i].getGeometry().getType() === 'Point') {
clusterSource.addFeature(geojsonFeatures[i]);
} else {
vectorSource.addFeature(geojsonFeatures[i]);
}
}
I have created a jsfiddle which gets a couple of features from a GeoJSON object and add them to different sources depending on the geometry type. If you want to see more points in the cluster souce to make sure that it is working properly, you can use the commented lines as well.

Customize style of a vector layer ol3

I use a geojson file to build the layer added to a map. What I want is to customize style of the layer's polygons in order to have hatched polygons such as we can do that with mapserver symbols. Is it possible to do this with ol3? I tried to create an image and use it but it only works for point geometry. Thank you for your help.
Regards.
Fill patterns for polygons are not (yet) supported in OpenLayers 3, see also https://github.com/openlayers/ol3/issues/2208
It is possible by now. The ol.style.Style object accepts a CanvasRenderingContext2D instance, where you can apply an image pattern to your polygons.
Example Code Snippet
var geojsonObject = 'someGeoJSON'
var source = new ol.source.Vector({
features: (new ol.format.GeoJSON()).readFeatures(geojsonObject)
});
var layer = new ol.layer.Vector({
source: source
});
var cnv = document.createElement('canvas');
var ctx = cnv.getContext('2d');
var img = new Image();
img.src = 'https://mdn.mozillademos.org/files/222/Canvas_createpattern.png';
img.onload = function() {
var pattern = ctx.createPattern(img, 'repeat');
layer.setStyle(new ol.style.Style({
fill: new ol.style.Fill({
color: pattern
})
}));
};
A full example can be seen here: jsfiddle

Drawing marker top of a line

I am trying to draw a line on top of another line using open layer. The idea is draw a second line top of the predefined line path.
How can we draw a line with starting coordinate and distance on top of the predefined line path?
You can do this by returning a 2nd style from your layer's style function, which has a custom geometry derived from the original one:
var lineStyle = new ol.style.Style(...); // your existing style
var secondLineStyle = new ol.style.Style({
... // styles for the 2nd line
geometry: function(feature) {
var geometry = feature.getGeometry().clone();
... // modify the geometry, e.g. using forEachSegment and getCoordinateAtM
return geometry;
}
});
var layer = new ol.layer.Vector({
style: function(feature, resolution) {
return [
lineStyle,
secondLineStyle
];
}
});

How to export a featureOverlay drawn on openlayers3 map (projection EPSG:3857) to a KML file projected to EPSG:4326

I am drawing polygons on a featureOverlay attached to openlayers3 map (projection EPSG:3857) as follows:
// create openlayers3 map
var map = new ol.Map({
layers: [
new ol.layer.Tile({
source: new ol.source.MapQuest({layer: 'sat'})
})
],
target: 'map',
view: new ol.View({
center: [-11000000, 4600000],
zoom: 4
})
});
// create the featureOverlay to receive polygons
var featureOverlay = new ol.FeatureOverlay();
featureOverlay.setMap(map);
// create the tool to draw polygons
draw = new ol.interaction.Draw({
features: featureOverlay.getFeatures(),
type: 'Polygon'
});
map.addInteraction(draw);
Until here, everything is ok! The idea is from oficial Draw features example. The next step is to export features drawn on the map to a KML file using projection EPSG:4326. I have tried to reach this task through the following code:
$('#download-button').click(function() {
// get the features drawn on the map
var features = featureOverlay.getFeatures().getArray();
// create an object to write features on a output KML file
var format = new ol.format.KML();
// write features to KML format using projection EPSG:4326
var kml = format.writeFeatures(features, 'EPSG:4326', 'EPSG:3857');
// Save KML node as KML file using FileSaver.js script
var str = (new XMLSerializer).serializeToString(kml);
var blob = new Blob([str], {type: "text/plain;charset=utf-8;"});
saveAs(blob, "NovaCamada.kml");
});
The main problem is KML file result always contains features with vertices on metrics units (I need degrees units!) even when shows the KML file on EPSG:4326.
The worst (and the purpose of my question) is that even when I change the piece of code that writes features to kml format to:
var kml = format.writeFeatures(features);
or:
var kml = format.writeFeatures(features, 'EPSG:3857', 'EPSG:4326');
the result is the same and nothing changes!
I expect ol.format.KML class converts the features from EPSG:3857 to EPSG:4326. Am I on the right way?
Do I need apply any reprojection on features before format it? Someone please could help me with this task?
Did I make myself clear?
P.S.: FileSaver.js
writeFeatures takes, as the 2nd argument, an object literal with two properties: dataProjection and featureProjection.
The KML format has a default dataProjection, EPSG:4326. This means you only need to specify the featureProjection in your case:
var result = kmlFormat.writeFeatures(features, {featureProjection: 'EPSG:3857'});
Unrelated note: we are changing the return type of writeFeatures in OpenLayers 3.1.0. writeFeatures will always return a string, for any format. This means you won't need to serialize the result of writeFeatures yourself with XMLSerializer.

Is it possible to add a icon symbol to a polygon

I am currently working on a openlayers 3 project and for better visulaizing i need to show both. The Polygon shape(attribute based color) which works great and an icon on the polygon position. I know that the polygon contains multiple coordinates and so its not so easy to define a position for the icon. Now i have some kind of workaround that creates an seperate overlay with the interior Points of the polygon to mark the position of the icons. To make the project more simple i want to combine these two styling. Does anyone know if its possible?
Kind Regards
I presumes that you use a ol.source.serversource for your data.
The trick is to test all your features for being a polygon. If it is, you create a point feature you add to your source.
First create the source and the layer:
var avlVectorSource = new ol.source.ServerVector({
format: new ol.format.GeoJSON(),
loader: function(extent, resolution, projection) {
myLoader(resolution);
}
});
var myLayer = new ol.layer.Vector({
source: myVectorSource,
style: myStyleFunction
});
The layer has a style function to set the right icon.
The main thing is the loader:
var myLoader = function(resolution){
$.ajax({
url: "http://myJsonSource.com",
timeout: 1000,
success: function(response) {
var layerJSONString = $.parseJSON(response);
var newFeatures = [];
j= 0;
var size=layerJSONString.features.length;
for (i = 0; i < size; i++){
var feat = layerJSONString.features[i];
var geom = feat.geometry;
var type = geom.type;
if(type == "Polygon")
{
var poly = new ol.geom.Polygon(geom.coordinates);
var extent = poly.getExtent();
var coord = [];
coord[0] = (extent[2]-extent[0])/2 + extent[0];
coord[1] = (extent[3]-extent[1])/2 + extent[1];
var point = new ol.geom.Point(coord);
newFeatures[j++] = new ol.Feature({
geometry : point,
StyleName : feat.properties.StyleName
});
}
}
avlVectorSource.addFeatures(myVectorSource.readFeatures(response));
avlVectorSource.addFeatures(newFeatures);
},
error: myLoadError
});
}
};
The documentation says that ol.geom.Polygon has a method called getInteriorPoint(). It has but I can get it to work. So I calculate the center point of the extent of the polygon.
I use "StyleName" to set the right icon in my style function.

Resources