Leaflet / Leaflet.draw

Vector drawing and editing plugin for Leaflet
https://leaflet.github.io/Leaflet.draw/docs/leaflet-draw-latest.html
MIT License
1.96k stars 992 forks source link

Angular - Resize Circle #1013

Open fabiopachecooss opened 3 years ago

fabiopachecooss commented 3 years ago

How to reproduce

when try to resize the circle

https://user-images.githubusercontent.com/83339630/116379608-783c6100-a813-11eb-8924-0561784dd34d.mp4

What behaviour I'm expecting and which behaviour I'm seeing

Minimal example reproducing the issue

ERROR ReferenceError: radius is not defined at NewClass._resize (leaflet.draw.js:9) at NewClass._onMarkerDrag (leaflet.draw.js:9) at NewClass.fire (leaflet-src.js:588) at NewClass._onDrag (leaflet-src.js:7333) at NewClass.fire (leaflet-src.js:588) at NewClass._updatePosition (leaflet-src.js:5929) at ZoneDelegate.invokeTask (zone-evergreen.js:399) at Object.onInvokeTask (core.js:41686) at ZoneDelegate.invokeTask (zone-evergreen.js:398) at Zone.runTask (zone-evergreen.js:167)

Using jsfiddle or another example site.

fabiopachecooss commented 3 years ago
drawnItems: L.FeatureGroup = L.featureGroup();
    options = {
        layers: [
            L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', { maxZoom: 18, attribution: 'Open Street Map' })
        ],
        zoom: 5,
        center: L.latLng({ lat: 46.879966, lng: -121.726909 })
    };

    drawOptions = {
        position: 'topright',
        draw: {
            marker: {
                icon: L.icon({
                    iconSize: [ 25, 41 ],
                    iconAnchor: [ 13, 41 ],
                        iconUrl: 'leaflet/marker-icon.png',
      iconRetinaUrl: 'leaflet/marker-icon-2x.png',
      shadowUrl: 'leaflet/marker-shadow.png'
                })
            },
      circle: {
        shapeOptions: {
            color: '#aaaaaa'
        }
      }
        },

        edit: {
            featureGroup: this.drawnItems
        }
    };

    drawLocal: any = {
        draw: {
            toolbar: {
                buttons: {
                    polygon: 'Draw an awesome polygon!'
                }
            }
        }
    };

  public onDrawCreated(e: any) {
        console.log('Draw Created Event!');

        const layer = (e as L.DrawEvents.Created).layer;
        this.drawnItems.addLayer(layer);
    }

    public onDrawStart(e: any) {
        console.log('Draw Started Event!');
    }

  onMapReady(map: L.Map) {}
fabiopachecooss commented 3 years ago
<div leaflet style="height: 700px"
     leafletDraw
     [leafletOptions]="options"
     [leafletDrawOptions]="drawOptions"
     [leafletDrawLocal]="drawLocal"
     (leafletDrawCreated)="onDrawCreated($event)"
     (leafletDrawStart)="onDrawStart($event)">

    <!-- Add the drawnItems featureGroup to the map -->
    <div [leafletLayer]="drawnItems"></div>

</div>
claudia9 commented 2 years ago

We get the same error. And we created this issue 3 years ago, without any response. https://github.com/Leaflet/Leaflet.draw/issues/945

It looks like a declaration of variable (var radius) would save the error. But they need to approve the pull request.

poet-of-the-fall commented 1 year ago

I think it was a missing variable declaration, should be fixed with this PR: https://github.com/Leaflet/Leaflet.draw/pull/1053

ferily7 commented 1 year ago

I am also having this same issue. @poet-of-the-fall Has this been resolved yet?

antoniovlx commented 12 months ago

It should be fixed with PR, but if you don't want find another plugin you can try this solution:

L.Edit.Circle is the class controlling the edition of the circle and it has a method call _resize. If a class is already defined, you can replace how a class method works using L.Class.include().

In our case:

L.Edit.Circle.include({
    _resize(){
        var moveLatLng = this._moveMarker.getLatLng();

        var radius = this._map.distance(moveLatLng, latlng);

        this._shape.setRadius(radius);

        if (this._map._editTooltip) {
            this._map._editTooltip.updateContent({
                text: L.drawLocal.edit.handlers.edit.tooltip.subtext + '<br />' + L.drawLocal.edit.handlers.edit.tooltip.text,
                subtext: L.drawLocal.draw.handlers.circle.radius + ': ' +
                L.GeometryUtil.readableDistance(radius, true, this.options.feet, this.options.nautic)
                });
            }

        this._shape.setRadius(radius);

        this._map.fire(L.Draw.Event.EDITRESIZE, {layer: this._shape});
    }
});
AdliAB commented 7 months ago

// Solution pour le redimensionnement du cercle avec Leaflet

// Après avoir rencontré des difficultés avec le redimensionnement du cercle dans Leaflet, j'ai développé une solution qui a fonctionné efficacement.

// Étapes de la solution : // 1. Création d'un marqueur personnalisé : J'ai créé un marqueur personnalisé et j'ai ajusté son icône pour qu'il ressemble à l'outil de dessin par défaut. // 2. Suivi du dernier marqueur ajouté : J'ai mis en place un mécanisme pour garder la trace du dernier marqueur ajouté au cercle, ce qui me permet de contrôler le redimensionnement de manière précise. // 3. Suppression des autres marqueurs : Pour éviter toute confusion, j'ai supprimé tous les autres marqueurs de redimensionnement une fois que le dernier marqueur est ajouté. // 4. Rendre l'ancien marqueur invisible : Pour assurer une manipulation fluide du cercle, j'ai utilisé une requête jQuery pour rendre l'ancien marqueur invisible.

public addCircleListenersOSM(circle: L.Circle) { document.querySelectorAll('.leaflet-marker-icon.leaflet-div-icon.leaflet-editing-icon.leaflet-edit-resize.leaflet-touch-icon.leaflet-zoom-animated.leaflet-interactive.leaflet-marker-draggable').forEach((element) => { // Assurez-vous que l'élément est un HTMLElement avant d'accéder à la propriété 'style' if (element instanceof HTMLElement) { const width = parseInt(element.style.width, 10); const height = parseInt(element.style.height, 10);

    if (width === 20 && height === 20) {
      // Cet élément correspond aux dimensions spécifiées, le rendre invisible
      element.style.opacity = '0';
    }
  }
});
 this.initializeResizeMarker(circle);

// Gestion du déplacement du cercle
circle.on('move', (event) => {
  const newCenter = event.target.getLatLng();
   this.updateResizeMarkerPosition(circle);
});

// Gestion du redimensionnement du cercle via le marqueur de redimensionnement
this.resizeMarker.on('drag', (event) => {
  const newLatLng = event.target.getLatLng();
  const newRadius = circle.getLatLng().distanceTo(newLatLng);
  circle.setRadius(newRadius);
  this.updateResizeMarkerPosition(circle); // Optionnel si vous voulez déplacer le marqueur de redimensionnement pendant le drag
});

}

private initializeResizeMarker(circle: L.Circle) { const resizeMarkerLatLng = this.calculatePointOnCircle(circle.getLatLng(), circle.getRadius());

this.removeExistingMarker(this.resizeMarker);

this.resizeMarker = L.marker(resizeMarkerLatLng, {
  draggable: true,
  icon: L.divIcon({
    className: 'leaflet-marker-icon leaflet-div-icon leaflet-editing-icon leaflet-touch-icon leaflet-zoom-animated leaflet-interactive leaflet-marker-draggable'
  ,iconSize: [21, 21]})
}).addTo(this.openMap);

}

private updateResizeMarkerPosition(circle: L.Circle) { if (this.resizeMarker) { const newLatLng = this.calculatePointOnCircle(circle.getLatLng(), circle.getRadius()); this.resizeMarker.setLatLng(newLatLng); } }

private removeExistingMarker(marker: L.Marker | null) { if (marker) { this.openMap.removeLayer(marker); } }

// Méthode pour calculer la position du marqueur de redimensionnement sur le bord du cercle private calculatePointOnCircle(center: L.LatLng, radius: number): L.LatLng { // Utiliser une approximation simple pour positionner le marqueur sur le bord du cercle const angle = Math.PI / 2; // 90 degrés en radians pour simplifier const dx = radius Math.cos(angle); const dy = radius Math.sin(angle); const earthRadiusMeters = 6371000; const dLat = dy / earthRadiusMeters (180 / Math.PI); const dLng = dx / (earthRadiusMeters Math.cos(Math.PI center.lat / 180)) (180 / Math.PI);

return L.latLng(center.lat + dLat, center.lng + dLng); } appeler cette methode au bon endroit .Cette approche m'a permis de manipuler le cercle proprement ! .