Leaflet Delete feature properties from GoeJson with button - onclick

I have simple code but can't get how to make it works.. The idea is to press the "Delete" button to change "area" value to "0" in each feature made in GeoJson. Code below works, (but automatically, without the button), and it is clear for me:
function onEachFeature(feature, layer) {
feature.properties.area = 'x';
};
But when I want start changing values using the button (I put function inside OnEachFeature) the operation works only for the last feature in geoJson file..
function onEachFeature(feature, layer) {
function foo(){
feature.properties.area = 'x';
}
document.getElementById('delete').onclick = foo;
};
My question is how to make it works for each feature (Press the button -> Change area value ) ?
I will be very grateful for your answers !
Below link for GeoJson file:
https://api.npoint.io/2ba17bdbb50601803cd0

You can use getLayers to get all the features and then change their area property:
var geojson = L.geoJSON(data, {
onEachFeature: onEachFeature
}).addTo(map);
function deleteArea() {
var layers = geojson.getLayers();
for (var i = 0; i < layers.length; i++) {
layers[i].feature.properties.area = 0;
}
}
document.getElementById('delete').onclick = deleteArea;

Related

PaperJS, Need to select items underneath a transparent raster using Mouse Down

I have a Canvas with multiple raster images.
I use onMouseDown on Tool to find select the item which was clicked.
I have a new requirement.
Suppose, two images overlap each other, and the upper image is partially transparent. That makes the lower image visible. But when I try to click on the lower image, obviously I end up choosing the upper image.
Failed Attempt
I tried to use the getPixel(point) function on Raster. I thought if I can figure that the selected pixel is transparent, I can ignore that raster and look for other items. But I am not getting the color value that I am expecting (transparent or not) using this function.
So, my second thought was that I need to change the mousedown event point from the global co-ordinate space to local raster co-ordinate space. It still did not work.
Is there a way to achieve what I want?
Code
tool.onMouseDown = (event) => {
project.activeLayer.children.forEach((item) => {
if (item.contains(event.point)) {
// check if hit was on a transparent raster pixel
const pixel = item.getPixel(event.point)
console.error(pixel.toCSS(true))
// 2nd attempt
const pixel = item.getPixel(item.globalToLocal(event.point))
console.error(pixel.toCSS(true))
}
}
}
There is a simpler way to do what you want to achieve.
You can rely on project.hitTestAll() method to do a hit test on all items.
Then, if the hit item is a raster, hit pixel color information will be contained in hitResult.color. hitResult.color.alpha is all you need to check if a raster was hit on a non-transparent pixel.
Here is a sketch demonstration of the solution.
const dataUrl = 'data:image/png;base64,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';
const lowOpacity = 0.3;
// create 2 rasters
new Raster({
source: dataUrl,
opacity: lowOpacity,
onLoad: function() {
this.position = view.center - 100;
}
});
new Raster({
source: dataUrl,
opacity: lowOpacity,
onLoad: function() {
this.position = view.center + 100;
}
});
// on mouse down
function onMouseDown(event) {
// unselect previously selected items
paper.project.selectedItems.forEach(item => {
item.selected = false;
item.opacity = lowOpacity;
});
// do a hit test on all project items
const hitResults = project.hitTestAll(event.point);
// for each hit result
for (let i = 0; i < hitResults.length; i++) {
const hitResult = hitResults[i];
// if item was hit on a non transparent pixel
if (hitResult && hitResult.color && hitResult.color.alpha > 0) {
// select item
hitResult.item.selected = true;
hitResult.item.opacity = 1;
// break loop
break;
}
}
}

Is it possible to arrows on a pageable container (visual composer)?

I'm working on my WordPress website with Visual Composer.
I need to include a pageable container but it would be great if it can be like a slideshow.
This is my pageable container
Thanks in advance,
Regards :)
Based upon the current version of WP Bakery Page Builder the below works for me:
To build it I created a row with 3 columns, with the pageable container in the middle column and the left and right arrow images in the columns on either side.
Both arrow images and the pageable container were given IDs. In my example the IDs of the arrows were #arrow_prev and #arrow_next respectively. You can give your pageable container any unique ID.
(function ($) {
$(document).ready(function(){
$( '#arrow_prev' ).click( function( e ) {
var pageable_container = $(this).closest(".vc_row").find(".vc_tta-panels-container");
move_pageable_container(pageable_container,'prev');
});
$( '#arrow_next' ).click( function( e ) {
var pageable_container = $(this).closest(".vc_row").find(".vc_tta-panels-container");
move_pageable_container(pageable_container,'next');
});
function move_pageable_container(pageable_container,direction){
// Make a list of the panel IDs
var panel_ids = $(pageable_container.find(".vc_tta-panel"))
.map(function() { return this.id; }) // convert to set of IDs
.get();
// Find position of the active panel in list
var current_active_pos = panel_ids.indexOf($(pageable_container).find(".vc_tta-panel.vc_active").attr('id'));
var new_pos = 0;
switch(direction) {
case 'prev':
if (current_active_pos > 0){
new_pos = current_active_pos-1;
}else{
new_pos = panel_ids.length-1;
}
break;
case 'next':
if (current_active_pos < panel_ids.length-1){
new_pos = current_active_pos+1;
}else{
new_pos = 0;
}
break;
}
// Clear active panels
$(pageable_container.find(".vc_tta-panel")).each(function(i,a) {
$(this).removeClass("vc_active");
});
var new_active_panel = $(pageable_container).find('#'+ panel_ids[new_pos]);
$(new_active_panel).addClass("vc_animating");
$(new_active_panel).addClass("vc_active");
setTimeout(
function(){
$(new_active_panel).removeClass("vc_animating");
}, 350);
}
}
);
})(jQuery);
If you want a pseudo fading-in effect then you can use this additional CSS in your style sheet:
#id_of_pageable_container .vc_tta-panel.vc_animating {
opacity: 0!important;
}
Where #id_of_pageable_container is the ID that you gave your pageable container
A simpler solution with vanilla js only:
The idea is to find the target page button and press it programmatically, so that there is no need to mimic the plugin's animations as in Chaz's solution.
Add js (via Raw JS widget / other means):
function prevSlide () {
const slides = document.getElementsByClassName('vc_pagination-item');
for (let i = 0; i < slides.length; i++) {
if (slides[i].className.includes('vc_active')) {
if (i - 1 < 0) return;
slides[i - 1].firstChild.click();
return;
}
}
}
function nextSlide () {
const slides = document.getElementsByClassName('vc_pagination-item');
for (let i = 0; i < slides.length; i++) {
if (slides[i].className.includes('vc_active')) {
if (i + 1 >= slides.length) return;
slides[i + 1].firstChild.click();
return;
}
}
}
Add button widgets and set href to call js:
For left arrow button,
javascript:prevSlide();
For right arrow button,
javascript:nextSlide();
Hope this helps.
I prefer to use the Post Grid widget for that. Keep in mind that the pageable container is not totally responsive, it doesn't react to swipe touching, but the Post Grid does.
Post Grid is really powerful, although it also has its caveouts. You can create your content with posts and pages, or a custom post type and then filter what you want to show in your slider from the widget options.
In "advanced mode" you can use the Grid Builder to create your own template and control the output.
The only problems that I've found with this method is to set a variable height in sliders and that sometimes it is slow loading content and is not possible to do a lazyload.

Change (and change back) leaflet icon on click

I've gotten the icon to change on click, but I need it to change back to the original icon (not stay the new one) when a new icon is clicked.
For instance, say all of my icons are blue. When I click on an icon, I want it to change to a red icon. Then, when I click on a new icon, I want the previously clicked icon to change back to blue.
I can get it to work with mouseover and mouseout, but I really need it to work with click. I think I need to log a new click function, but I'm not sure how.
Here's what I currently have:
function clickFeature(e) {
var layer = e.target;
e.target.setIcon(stop);
info.update(layer.feature.properties);
}
var geojson;
/*function resetHighlight(e) {
geojson.resetStyle(e.target);
e.target.setIcon(arms);
info.update();
}*/
function onEachFeature(feature, layer) {
layer.on({
click: clickFeature
});
}
geojson = L.geoJson(crossingData, {
pointToLayer: function (feature, latlng) {
return L.marker(latlng, {icon: arms});
},
onEachFeature: onEachFeature
}).addTo(map);
You can try to define seprate variable outside of function, that will hold currently clicked marker.
var clickedMarker;
function clickFeature(e) {
if(clickedMarker) {
clickedMarker.setIcon(arms);
}
var layer = e.target;
e.target.setIcon(stop);
clickedMarker = e.target;
info.update(layer.feature.properties);
}
You should get current icon for change to another one. Unfortunately L.marker has no getIcon() method, but you can access it via options.icon.
function clickFeature(e) {
var layer = e.target;
layer.setIcon(layer.options.icon == arms ? stop : arms);
}

Multiple marker selection within a box in leaflet

I need to select multiple markers in a map. Something like this: Box/Rectangle Draw Selection in Google Maps but with Leaflet and OSM.
I think it could be done by modifying the zoom box that appears when you shift click and drag in an OSM map, but I don't know how to do it.
Edit:
I rewrote the _onMouseUp function, as L. Sanna suggested and ended up with something like this:
_onMouseUp: function (e) {
this._finish();
var map = this._map,
layerPoint = map.mouseEventToLayerPoint(e);
if (this._startLayerPoint.equals(layerPoint)) { return; }
var bounds = new L.LatLngBounds(
map.layerPointToLatLng(this._startLayerPoint),
map.layerPointToLatLng(layerPoint));
var t=0;
var selected = new Array();
for (var i = 0; i < addressPoints.length; i++) {
var a = addressPoints[i];
pt = new L.LatLng(a[0], a[1]);
if (bounds.contains(pt) == true) {
selected[t] = a[2];
t++;
}
}
alert(selected.join('\n'))
},
I think it could be easy modificating the zoom box that appears when
you shift clic and drag in an osm map, but I don't know how to do it
Good idea. The zoom Box is actually a functionality of leaflet.
Here is the code.
Just rewrite the _onMouseUp function to fit your needs.
Have you tried something like this?
markers is an array of L.latLng() coordinates
map.on("boxzoomend", function(e) {
for (var i = 0; i < markers.length; i++) {
if (e.boxZoomBounds.contains(markers[i].getLatLng())) {
console.log(markers[i]);
}
}
});
Not enough points to comment, but in order to override the _onMouseUp function like OP posted in their edit, the leaflet tutorial gives a good explanation. Additionally, this post was very helpful and walks you through every step.
A bit late to the party but it's also possible to achieve this using the leaflet-editable plugin.
// start drawing a rectangle
function startSelection() {
const rect = new L.Draw.Rectangle(this.map);
rect.enable();
this.map.on('draw:created', (e) => {
// the rectangle will not be added to the map unless you
// explicitly add it as a layer
// get the bounds of the rect and check if your points
// are contained in it
});
}
Benefits of using this method
Allow selection with any shape (polygon, circle, path, etc.)
Allow selection using a button/programmatically (does not require holding down the shift key, which may be unknown to some users).
Does not change the zoom box functionality

how to hide vector features in openlayers

I have written some code to hide specific markers in our maps based on checkboxes outside of the map itself. However, these markers also have vector features too (really on separate layers) but I want to just hide the features rather than destroy them. I tried using display(false) but get errors. Is there a function for hiding vectors?
Solution
Change the style property for OpenLayers.Feature.Vector instances. Set the display attribute to none or the visibility attribute to hidden. Redraw the layer afterwards.
According to comments in OpenLayers code:
display - {String} Symbolizers will have no effect if display is set to "none". All other values have no effect.
Example Code
For a given OpenLayers layer variable called layer, you could hide all the features as follows:
var features = layer.features;
for( var i = 0; i < features.length; i++ ) {
features[i].style = { visibility: 'hidden' };
}
layer.redraw();
This iterates over all features in a layer, allowing full control of the specific features to hide.
I have wrestled with OpenLayers a few times trying to get my features within the same layer to display exactly as I want. #igorti's solution overrides all of the feature's style properties, so I don't recommend this approach unless you have no reason to re-display the feature later on (in which case the removeFeatures() method is probably a better way to do this anyways).
Hiding Vector Features
The way I do this is to manually set the feature's style display to none and then redraw the layer. If I need to display the feature again, set the display property to block. Pretty simple:
function hideFeatures() {
var features = layer.features;
for (var i = 0; i < features.length; i++) {
var feature = features[i];
if (!isVisible(feature)) {
feature.style.display = 'none';
}
}
layer.redraw();
}
Re-Displaying Vector Features
Re-displaying hidden features is a little bit trickier depending on your situation. Take a look at the OpenLayers documentation on styling for some possibilities. But in general, if I need to display the feature again, I set the feature's style attribute to null. This ensures that when the OpenLayers renderer performs the drawFeature function, your pre-configured styles from your layer's styleMap are redrawn:
// from OpenLayers drawFeature()
if (!style) {
style = this.styleMap.createSymbolizer(feature, renderIntent);
}
So your display function might look something like this:
function displayFeatures() {
var features = layer.features;
for (var i = 0; i < features.length; i++) {
var feature = features[i];
if (isVisible(feature)) {
feature.style = null; //redraw the feature
}
}
layer.redraw();
}
Other Approaches
There are a couple other approaches to doing this. You can set the feature's fillOpacity and strokeOpacity to 0, like so:
function displayFeatures() {
var features = layer.features;
for (var i = 0; i < features.length; i++) {
var feature = features[i];
if (isVisible(feature)) {
feature.style.fillOpacity = 1;
feature.style.strokeOpacity = 1;
}
else {
feature.style.fillOpacity = 0;
feature.style.strokeOpacity = 0;
}
}
layer.redraw();
}
The downside to this approach is that any active map controls will still be able to interact with the "hidden" feature, so if a user accidentally clicks or hovers over the feature these events will still fire.
You can also create a style within your layer's styleMap called hidden, with either of the two approaches above. Then to hide a feature, simply change the feature's renderIntent to hidden.
Finally, you can add subsets of your features to separate layers, and call the layer's setVisibility method to false. This is only a good option if you don't have a need to interact with all features concurrently, since only controls for the top layer of your map will be active. (There are ways to use controls for multiple layers, but there's a lot more juggling involved and I don't recommend it unless it is absolutely necessary)
You can set display:'none' in style property. So that features will not be display
To hide features
for( var i = 0; i < features.length; i++ ) {
features[i].style = { display: 'none' };
}
layer.redraw();
To display back the hidden features
for( var i = 0; i < features.length; i++ ) {
features[i].style = null;
}
layer.redraw();
To hide the one feature
var feature = vectorlayer.getFeatureByFid(fid);
feature.style = { display: 'none' };
vectorLayer.removeFeatures(feature);
vectorLayer.addFeatures(feature);
It was not clear from your question whether you've already tried it, but if you haven't you might try the setVisibility() method.
Reference: http://dev.openlayers.org/releases/OpenLayers-2.10/doc/apidocs/files/OpenLayers/Layer-js.html#OpenLayers.Layer.setVisibility
Here is what I finally done for this matter as I had the same need but didn't want to hide each feature individually or play with CSS style:
I'll assume that you have something like the following somewhere:
myVector = new OpenLayers.Layer.Vector(...
Then link this code to the button or whatever event you need:
if( myVector.getVisibility() && myVector.features.length > 0 ) {
myVector.setVisibility(false);
} else {
myVector.setVisibility(true);
}
getVisibility() / setVisibility() references are missing from vector part but are in layer documentation.

Resources