Viglino / ol-ext

Cool extensions for Openlayers (ol) - animated clusters, CSS popup, Font Awesome symbol renderer, charts for statistical map (pie/bar), layer switcher, wikipedia layer, animations, canvas filters.
https://viglino.github.io/ol-ext/
Other
1.24k stars 462 forks source link

ol.control.EditBar #727

Closed ngjiajunsg closed 2 years ago

ngjiajunsg commented 2 years ago

Hi Viglino,

i got some issue when i intergate EditBar with PopupFeature.

  1. the popupfeature keep appear when i drawing
  2. for drawing how to stop the drawing like (https://openlayers.org/en/latest/examples/measure.html) to stop drawing is double click
  3. how to stop the drawing and return back to normal state where i able to select/click feature to display the information
Viglino commented 2 years ago

Hi,

  1. You have to close the PopupFeature on drawstart event (popup.hide() or clear selection)
  2. this is the standard behavior of the tool...
  3. You have to listen to drawend event and de-activate the interaction to stop using it
    // Remove popup on drawstart (clear selection)
    edit.getInteraction('DrawLine').on('drawstart', function() {
    edit.getInteraction('Select').getFeatures().clear();
    });
    // Stop drawing on drawend
    edit.getInteraction('DrawLine').on('drawend', function() {
    edit.getInteraction('DrawLine').setActive(false);
    });
ngjiajunsg commented 2 years ago

Hi Viglino,

i try the below code both

1) // Remove popup on drawstart (clear selection) edit.getInteraction('DrawLine').on('drawstart', function() { edit.getInteraction('Select').getFeatures().clear(); });

2) popup.hide();

both does not work 1) - the PopupFeature still appear with blank information 2) - error : Uncaught TypeError: popup.hide is not a function

i notice if integrate with PopupFeature, seem like my drawing point does not work.

Viglino commented 2 years ago

Do you have an online example?

ngjiajunsg commented 2 years ago

this are the code

<!DOCTYPE html>

ol-ext: Edit bar
Viglino commented 2 years ago

Can you create a pen on Codepen?

ngjiajunsg commented 2 years ago

Hi Viglino,

ok i will create a pen . sorry about it

https://codepen.io/ngjiajun/full/wvrRmML

Viglino commented 2 years ago

You have to use the select interaction of the edit bar edit.getInteraction('Select') to handle the popup (ie. show poup when selected). Otherwise, you have to deactivate the selection when drawing to prevent selection/popup to interfere with the drawing itself. See line 287 > https://codepen.io/viglino/pen/wvrRYPE

ngjiajunsg commented 2 years ago

thank Viglino,

some questions on the edit bar.

  1. For features that i create using edit bar, am i able to update the name of the feature? (for example a point and label them or a line to label it)
  2. for any features that are edit, am i able to update/save the information such as the lat, long of the position that i change.
Viglino commented 2 years ago
  1. You can add your own buttons to open a form and edit selected features as well. You can use the [i] button to do that for example.
  2. You can get all interactions in the bar to get informed when a feature is modified and do something (save position).
    edit.getInteraction('DrawLine').on('drawstart', (e) => {
    var feature = e.feature;
    // Save the geometry
    var geom = feature.getGeometry()
    ...
    })
ngjiajunsg commented 2 years ago

sorry i dont understand the logic on the "You can add your own buttons to open a form and edit selected features as well. You can use the [i] button to do that for example."

also can i check with you, how can i remove icons from the editbar, for example just display only drawline and draw polygon?

Viglino commented 2 years ago

In the exemple click on the info button display a notification:

    edit.on('info', function(e){
      console.log(e)
      note.show('<i class="fa fa-info-circle"></i> '+e.features.getLength()+' feature(s) selected');
    });

You can use it to display a form to change feature attributes;

    edit.on('info', function(e){
      var feature = e.features.item(0); // e.features[0] is a Collection
      if (feature) {
         var label = prompt('label');
         feature.set('label', label);
      }
    });

You can also add your own control to the bar:

var editAttr = new ol.control.Button({
  html: 'E',
  title: "attributes",
  handleClick: function() {
    var f = edit.getInteraction('Select').getFeatures().item(0)
    if (f) {
     var label = prompt('label');
     f.set('label', label);
    }
  }
});
edit.addControl (editAttr);
ngjiajunsg commented 2 years ago
 edit.on('info', function(e){
      var feature = e.features[0];
      if (feature) {
         var label = prompt('label');
         features.set('label', label);
      }
    });

i try add this code but seem like the var feature = e.features[0]; is undefined

Viglino commented 2 years ago

Ok! e.features is not an array but a Collection, try e.features.item(0) instead 😃

Viglino commented 2 years ago
edit.on('info', function(e){
  var feature = e.features.item(0);
  if (feature) {
     var label = prompt('label');
     feature.set('label', label);
  }
});
ngjiajunsg commented 2 years ago

Hi Viglino,

can i check with you wonder am i able restrict users to move anything from the map.. example https://codepen.io/viglino/pen/wvrRYPE

i have 3 locations point which i dont want users to move it.. is there any other way?

Viglino commented 2 years ago

The default modify interaction in the edit bar use the selected feature but you can set your own modify interaction on creation. The ModifyFeature interaction lets you add a filter function decide if the feature has to be modified or not. See http://viglino.github.io/ol-ext/doc/doc-pages/ol.interaction.ModifyFeature.html Something like that:

edit = new ol.control.Bar({
  interactions: {
     ModifySelect: new ol.interaction.ModifyFeature({
       filter: function(f) {
         // Test if feature can be modified
         if (isModif(f)) return true;
         else return false;
       }
  }
})
Viglino commented 2 years ago

I've added a setFilter method to let you change the filter directly:

edit.getInteraction('ModifySelect').setFilter(function(f) {
//edit.getInteraction('ModifySelect', function(f) {
   if (isModif(f)) return true;
   else return false;
})
ngjiajunsg commented 2 years ago

Sorry i dont get it as i implement the

edit.getInteraction('ModifySelect', function(f) {
   if (isModif(f)) return true;
   else return false;
})

but i still able to move the fixed feature

Viglino commented 2 years ago

Sorry setFilter() was missing, the code should be:

edit.getInteraction('ModifySelect').setFilter(function(f) { 
   if (isModif(f)) return true;
   else return false;
})
ngjiajunsg commented 2 years ago

Hi Viglino,

Sorry, seem like now all the features unable to edit/modfiy. even newly created from the editbar

in addition, now i also able to delete alway all the predrawn feature

ngjiajunsg commented 2 years ago

Hi Viglino,

can check with you if i wish the measurement to remain on the features issit possible? and in addition for circle can i check if i draw with shift and ctrl why it show the area of the circle instead of the radius?

Viglino commented 2 years ago

If you want to add information on feature you have to do it by yourself on drawend event.

While drawing you can check the current drawing and modify the tooltip content.

var regular = edit.getInteraction('DrawRegular');
regular.on('drawing', function(e) {
  // Circle?
  if (e.centered && e.square && regular.getSides()<3) {
    // Calculate Length
    var length = ol.sphere.getDistance( ol.proj.toLonLat(e.startCoordinate), ol.proj.toLonLat(e.coordinate) );
    // set measure
    tooltip.set('measure', tooltip.formatLength(length));
  }
})
ngjiajunsg commented 2 years ago

Hi Viglino,

Sorry, seem like now all the features unable to edit/modfiy. even newly created from the editbar

in addition, now i also able to delete alway all the predrawn feature

Viglino commented 2 years ago

The edition is controlled by the filter you give. Try display the test on console to see what's wrong:

edit.getInteraction('ModifySelect').setFilter(function(f) {
   console.log('TEST', f, isModif(f));
   if (isModif(f)) return true;
   else return false;
})
ngjiajunsg commented 2 years ago

Hi Viglino,

i got this error.

Uncaught ReferenceError : isModif is not defined at ol.interaction.ModifyFeature.filterSplit_ at ol.interaction.ModifyFeature.getClosestFeature (ol-ext.js:22969)

i try put this code in codepen (https://codepen.io/ngjiajun/pen/wvrRmML) still the same

[Uncaught ReferenceError: isModif is not defined at https://cdpn.io/cpe/boomboom/index.html?editors=1011&key=index.html-4c07c6af-6231-0790-34b3-3a8499428ec5:213]

ngjiajunsg commented 2 years ago

Hi Viglino,

can i check whether i am able to put the measure label display after measure (https://openlayers.org/en/latest/examples/measure.html)

Viglino commented 2 years ago

You have to define your own filter function (isModif) to test if the feature is modifiable or not... Return true if the feature is modifiable or `false if not...

ngjiajunsg commented 2 years ago

If you want to add information on feature you have to do it by yourself on drawend event.

While drawing you can check the current drawing and modify the tooltip content.

var regular = edit.getInteraction('DrawRegular');
regular.on('drawing', function(e) {
  // Circle?
  if (e.centered && e.square && regular.getSides()<3) {
    // Calculate Length
    var length = ol.sphere.getDistance( ol.proj.toLonLat(e.startCoordinate), ol.proj.toLonLat(e.coordinate) );
    // set measure
    tooltip.set('measure', tooltip.formatLength(length));
  }
})

Hi Viglino, can check if i want to display both area and distance together?

issit by adding to the area computation into tooltip.set method?

ngjiajunsg commented 2 years ago

You have to define your own filter function (isModif) to test if the feature is modifiable or not... Return true if the feature is modifiable or `false if not...

can check issit the isModif function workflow should be like

  1. check the layer issit drawing layer if yes is true else is false?
Viglino commented 2 years ago
  1. You can set what you want in the measure property of the tooltip: tooltip.set('measure', 'blabla: ' + length + ' - ' + area);

  2. The filter function in the ModifySelect interaction only get the selected feature. You don't have access to the layer at this step. You have to store the layer as a feature property when inserted in the layer if you want to retrieve it...

ngjiajunsg commented 2 years ago

Hi Viglino,

can i check whether i am able to put the measure label display after measure (https://openlayers.org/en/latest/examples/measure.html)

how can i set the label display after measure for line, shape and polygon?? issit that i need to

output =  ol.sphere.getDistance( ol.proj.toLonLat(e.startCoordinate), ol.proj.toLonLat(e.coordinate) );
tooltip.innerHTML = tooltip.formatLength(output );
tooltip.setPosition(e.coordinate);
ngjiajunsg commented 2 years ago
  1. The filter function in the ModifySelect interaction only get the selected feature. You don't have access to the layer at this step. You have to store the layer as a feature property when inserted in the layer if you want to retrieve it...

do you mean by this

var DrawingLayer = new ol.layer.Vector({ source: new ol.source.Vector({ layer: 'Drawing Layer' }), title: "Drawing Layer" });

Viglino commented 2 years ago

how can i set the label display after measure for line, shape and polygon?? issit that i need to

tooltip.set('measure', any_string_you_want);

Viglino commented 2 years ago
  1. You have to store the layer on the feature when you insert it to get the layer back when you have to know it:
    source.on('addfeature', function(f) { 
    f.set('layer', layer) 
    });
    // then you can get layer's back: f.get('layer')
ngjiajunsg commented 2 years ago

how can i set the label display after measure for line, shape and polygon?? issit that i need to

tooltip.set('measure', any_string_you_want);

i wish to display the measurement at the end of the drawing

https://ibb.co/S78jcvp

String

https://ibb.co/41bwWzd

Polygon

ngjiajunsg commented 2 years ago
  1. You have to store the layer on the feature when you insert it to get the layer back when you have to know it:
source.on('addfeature', function(f) { 
  f.set('layer', layer) 
});
// then you can get layer's back: f.get('layer')

i understand for my own code i able to store this line of code. but for editbar the drawing how should i add the line of code above for all kinds of drawing

for example

edit.getInteraction('DrawPoint').on('change:active', function(e){
      tooltip.setInfo(e.oldValue ? '' : 'Click map to place a point...');
    });
    edit.getInteraction('DrawLine').on(['change:active','drawend'], function(e){
      tooltip.setFeature();
      tooltip.setInfo(e.oldValue ? '' : 'Click map to start drawing line...');
    });

i not sure where should i put it for point and the same for line and poly and shapes

Viglino commented 2 years ago

i wish to display the measurement at the end of the drawing

The editbar example show you how to display measure while drawing. If you want to display information after drawing, just use a Popup.

i understand for my own code i able to store this line of code. but for editbar the drawing how should i add the line of code above for all kinds of drawing

You said you want to know the layer the feature belong to.

can check issit the isModif function workflow should be like : check the layer issit drawing layer if yes is true else is false?

But there is no link between features and layers with ol (the same feature can be in many layers). So you have to set the layer as an attribute on feature insertion (source.on('addfeature', function(f) { f.set('layer', layer) });) to get it back when needed and test in your isModif function...