Restricting pointermove interactions to two layers in openlayers 3 - javascript

In openlayers version v3.6 running in Chrome on Ubuntu
I have create a map with several layers (foo, bar, beltch) in it using the syntax:
layers:[foo,bar,beltch],
I would like to limit interactions to the layers foo and bar
The api documents at http://openlayers.org/en/master/apidoc/ol.interaction.Select.html
suggest using the following syntax
var selectPointerMove = new ol.interaction.Select({
condition: ol.events.condition.pointerMove,
layers:[foo,bar]
});
But I seem to get events for all layers, I have checked the examples and nothing seem to cover this area unless I have overlooked something.
Does anybody have any suggestions

Use filter instead of layers. And make sure you set a layer property to compare later.
var layerFeatures = new ol.layer.Vector({
name: 'selectable',
source: sourceFeatures
});
var hoverInteraction = new ol.interaction.Select({
condition: ol.events.condition.pointerMove,
filter: function(feature, layer){
if(layer.get('name') === 'selectable')
return true;
}
});

Related

OpenLayers I am not able to drag the custom features

Following the query here:
Openlayers can't modify drawn features
I have built some code, which allowes me to edit nodes of my drawn features:
var modifyInteraction = new ol.interaction.Modify({
features: selectInteraction.getFeatures(),
deleteCondition: function(event) {
return ol.events.condition.shiftKeyOnly(event) &&
ol.events.condition.singleClick(event);
}
});
map.addInteraction(modifyInteraction);
However I have lost the option for dragging my features, which is defined by this code:
var translateInteraction = new ol.interaction.Translate({
features: selectInteraction.getFeatures(),
});
map.addInteraction(translateInteraction);
The new ol.interaction.Translate({ has been switched off, otherwise I am not able to edit my features, but I can only drag them.
Is there any chance to make my features draggable when I can edit them like defined in the code new ol.interaction.Modify({ above?
My full JSfiddle is here:
https://jsfiddle.net/g196cqoa/
You can add a condition option to the translate interaction to only interact when ctrl key is pressed.
var modifyInteraction = new ol.interaction.Modify({
features: selectInteraction.getFeatures(),
deleteCondition: function(event) {
return ol.events.condition.shiftKeyOnly(event) &&
ol.events.condition.singleClick(event);
},
});
map.addInteraction(modifyInteraction);
const translate = new ol.interaction.Translate({
features: selectInteraction.getFeatures(),
condition: function (event) {
return ol.events.condition.platformModifierKeyOnly(event) &&
ol.events.condition.primaryAction(event);
},
});
map.addInteraction(translate);
Alternatively, if you add the translate interaction before the modify interaction it should allow you to drag polygons as long as you stay away from the edges. This won't work with lines and points. as there is no area where the geometry cannot be modified.
The order in which the interactions are added to the maps interaction collection determines whether the modify interaction is allowed see and handle the events before the translate interaction handles them

Heatmap Renderer ArcGIS Javascript 4.4 based on number of points and their locality to each other in the layer only

I have been reviewing the documentation for the heatmap renderer but I would like to tag it to my feature layer without visualising based on the "field" but based on the number of points and their locality between each other. Could anyone advise me how to?
var earthquakeLayer = new FeatureLayer({
// url to a point dataset
});
// visualization based on field
var heatmapParams = {
layer: earthquakeLayer,
view: view,
field: "magnitude"
};
// when the promise resolves, apply the renderer to the layer
heatmapRendererCreator.createRenderer(heatmapParams)
.then(function(response){
earthquakeLayer.renderer = response.renderer;
});
I think what you are actually looking for clustering features (ArcGIS API Doc - FeatureReductionCluster). There are several examples there, take a look if it fits your needs.

Sort order of layers in Leaflet layer control

I have created a leaflet map to display some geoJSON data in separate vertical layers.
It works fine, except that the layer control will list the options out of order, i.e. "layer 0, layer 2, layer 1" as opposed to "layer 0, layer 1, layer 2". The data is loaded through AJAX calls, and so the layers are added to the control in the order which the calls complete, i.e. basically random.
According to the documentation for the layer control [ https://leafletjs.com/reference-1.3.0.html#control-layers ], if sortLayers is set to true, the default is to sort the layers by name, but that seems to not be happening.
So, I have tried passing in a sort function explicitly, but the doc does not give an example of what one should look like.
When my code looks like this:
var layerControlOptions = {
hideSingleBase : true,
autoZIndex : true,
sortLayers: true}
var layerControl = L.control.layers(null, null, layerControlOptions).addTo(map);
The control looks like this:
layer control with sortLayers: true and no sortFunction being defined
My best guess at writing my own sorting function:
var layerControlOptions = {
hideSingleBase : true,
autoZIndex : true,
sortLayers: true,
sortFunction: function(layerA, layerB, nameA, nameB){return
[nameA,nameB].sort();}}
var layerControl = L.control.layers(null, null,
layerControlOptions).addTo(map);
With this, the layer names appear in the same order as when no function is given. Not sure if I am writing it incorrectly, or it is simply equivalent to the default, which is returning the wrong order for some reason.
Seems like the same issue here: Leaflet Layer Control: Ordering
which has no accepted answer and makes no mention of the layer control options. I did try the solution which is proposed here, but it did not fix the problem either.
Any help on this would be greatly appreciated, thank you.
You may look at this solution to order layers in the controls (it does not order layers). I've mainly borrowed code from Leaflet specs code;
If you have not problem to sort things in the control but you have issue related to loading JSON/GeoJSON (hence layer too) in a particular order, you may want to combine fetch with Promise.all but it's not anymore about Leaflet but about JavaScript knowledge (look at this page to try to grasp fetch + Promise.all)
You can add the layers as you normally would and then sort them with a function that removes labels and re-add them as sorted.
function sortLabels() {
var controlLayers = {}
layerControl._layers.forEach(function(x) {
if (x.overlay) {
controlLayers[x.name] = x.layer
}
});
names = Object.keys(controlLayers).sort()
//remove and add sorted layernames
names.forEach(x => layerControl.removeLayer(controlLayers[x]))
names.forEach(x => layerControl.addOverlay(controlLayers[x], x))
}
var baseMaps = { "OpenStreetMap": tile_layer_osm, "ESRI World Imagery" : esri_satelite };
var overlayMaps = {nameC: layerC, nameA: layerA, nameB: layerB}
var layerControl = L.control.layers(baseMaps, overlayMaps, null, {collapsed: false}).addTo(map);
sortLabels()

Openlayers 3. Clusters

I use Openlayers 3. I have a layer with clustering:
var layer = new ol.layer.Vector({
source: new ol.source.Cluster({
distance: 10,
source: new ol.source.Vector({
features: []
})
})
});
I add two features to it this way:
this.feature1 = <some feature with style>;
this.feature2 = <some feature with style>;
layer.getSource().getSource().addFeature(this.feature1);
layer.getSource().getSource().addFeature(this.feature2);
Then I want to hide my features by setting theire styles to null:
this.feature1.setStyle(null);
this.feature2.setStyle(null);
So, on the map these features are not visible. But if these features are placed close to each other, the cluster marker is shown. So, my question is the next: is any way not to consider features with empty style in clustering?
You can specify a "geometryFunction" parameter whey you create your Cluster source.
This function will get called and give you the ability to determine what should be included in the cluster.

Styling a geoJSON Feature Layer in MapBox

I just started playing with MapBox and am running into a confusing issue. I'm creating a map with a geoJSON layer using this code:
var map = L.mapbox.map('map', '<MapBoxID>');
var zipLayer = L.mapbox.featureLayer('data/blah.json');
zipLayer.addTo(map);
zipLayer.setStyle({color: 'red'});
The map appears and shows the geoJSON, but it ignores the styling. When I copy that last line into the JS console in my browser, it works fine, though.
What am I missing here? Also, I've tried at least a dozen different ways of including the style in the options directly in the featureLayer() call, but nothing has worked. How do I specify the style when creating the feature layer?
I'm guessing a bit here, since I don't know the Mapbox JS very well, but it sounds a lot like an async error. Strangely, I don't see anything in the Mapbox or Leaflet APIs about a callback for this function. But, you can pass straight GeoJSON to featureLayer(), so I'd suggest using jQuery (or your XHR library of choice) to grab the data:
var map = L.mapbox.map('map', '<MapBoxID>');
var zipLayer;
$.getJSON('data/blah.json', function(data) {
zipLayer = L.mapbox.featureLayer(data);
zipLayer.addTo(map);
zipLayer.setStyle({color: 'red'});
});
Hopefully that'll do the trick.
I would go the route of using the built-in featureLayer function, then listening for it to be ready. This should help get you pointed in the right direction:
var featureLayer = L.mapbox.featureLayer()
.loadURL('/example-single.geojson')
.on('ready', function(layer) {
this.eachLayer(function(marker) {
// See the following for styling hints:
// https://help.github.com/articles/mapping-geojson-files-on-github#styling-features
marker.setIcon(L.mapbox.marker.icon({
'marker-color': '#CC0000'
}));
});
})
.addTo(map);
Have you tried adding the zipLayer after setting the style?

Categories

Resources