Leaflet.draw
Leaflet.draw copied to clipboard
Angular - Resize Circle
- [x ] I'm reporting a bug, not asking for help
- [ ] I've looked at the documentation to make sure the behaviour is documented and expected
- [ ] I'm sure this is a Leaflet Draw code issue, not an issue with my own code nor with the framework I'm using (Cordova, Ionic, Angular, React…)
- [ ] I've searched through the issues to make sure it's not yet reported
How to reproduce
when try to resize the circle
- Leaflet version I'm using:
- Leaflet Draw version I'm using:
- Browser (with version) I'm using:
- OS/Platform (with version) I'm using:
- step 1
- step 2
https://user-images.githubusercontent.com/83339630/116379608-783c6100-a813-11eb-8924-0561784dd34d.mp4
- "@asymmetrik/ngx-leaflet": "^8.1.0", "@asymmetrik/ngx-leaflet-draw": "^7.0.0", "leaflet": "^1.7.1", "leaflet-draw": "^1.0.4",
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)
- [x ] this example is as simple as possible
- [ ] this example does not rely on any third party code
Using jsfiddle or another example site.
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) {}
<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>
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.
I think it was a missing variable declaration, should be fixed with this PR: https://github.com/Leaflet/Leaflet.draw/pull/1053
I am also having this same issue. @poet-of-the-fall Has this been resolved yet?
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});
}
});
// 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 ! .