Polygon draw working

pull/1530/head
Piero Toffanin 2024-07-29 13:31:48 -04:00
rodzic 2046a6f447
commit 881305052b
3 zmienionych plików z 221 dodań i 3 usunięć

Plik binarny nie jest wyświetlany.

Po

Szerokość:  |  Wysokość:  |  Rozmiar: 4.8 KiB

Wyświetl plik

@ -15,6 +15,11 @@ import exifr from '../vendor/exifr';
import '../vendor/leaflet/leaflet-markers-canvas';
import { _, interpolate } from '../classes/gettext';
const Colors = {
fill: '#fff',
stroke: '#1a1a1a'
};
class MapPreview extends React.Component {
static defaultProps = {
getFiles: null
@ -47,12 +52,15 @@ class MapPreview extends React.Component {
maxZoom: 24
});
this.group = L.layerGroup();
this.group.addTo(this.map);
// For some reason, in production this class is not added (but we need it)
// leaflet bug?
$(this.container).addClass("leaflet-touch");
//add zoom control with your options
let zoomControl = Leaflet.control.zoom({
Leaflet.control.zoom({
position:'bottomleft'
}).addTo(this.map);
@ -241,11 +249,204 @@ _('Example:'),
const { cropping } = this.state;
let crop = !cropping;
if (!crop) this.cropButton.blur();
if (!crop) {
if (this.captureMarker) {
this.captureMarker.off('click', this.handleMarkerClick);
this.captureMarker.off('dblclick', this.handleMarkerDblClick);
this.captureMarker.off('mousemove', this.handleMarkerMove);
this.captureMarker.off('contextmenu', this.handleMarkerContextMenu);
this.map.off('move', this.onMapMove);
this.map.off('resize', this.onMapResize);
this.group.removeLayer(this.captureMarker);
this.captureMarker = null;
}
if (this.acceptMarker) {
this.group.removeLayer(this.acceptMarker);
this.acceptMarker = null;
}
if (this.measureBoundary) {
this.group.removeLayer(this.measureBoundary);
this.measureBoundary = null;
}
if (this.measureArea) {
this.group.removeLayer(this.measureArea);
this.measureArea = null;
}
this.cropButton.blur();
}
else{
if (!this.captureMarker) {
this.captureMarker = L.marker(this.map.getCenter(), {
clickable: true,
zIndexOffset: 10001
}).setIcon(L.divIcon({
iconSize: this.map.getSize().multiplyBy(2),
className: "map-preview-marker-layer"
})).addTo(this.group);
this.captureMarker.on('click', this.handleMarkerClick);
this.captureMarker.on('dblclick', this.handleMarkerDblClick);
this.captureMarker.on('mousemove', this.handleMarkerMove);
this.captureMarker.on('contextmenu', this.handleMarkerContextMenu);
this.map.on('move', this.onMapMove);
this.map.on('resize', this.onMapResize);
}
if (this.polygon){
this.group.removeLayer(this.polygon);
this.polygon = null;
}
// Reset latlngs
this.latlngs = [];
}
this.setState({cropping: !cropping});
}
handleMarkerClick = e => {
L.DomEvent.stop(e);
const latlng = this.map.mouseEventToLatLng(e.originalEvent);
this.uniqueLatLonPush(latlng);
if (this.latlngs.length >= 1) {
if (!this.measureBoundary) {
this.measureBoundary = L.polyline(this.latlngs.concat(latlng), {
clickable: false,
color: Colors.stroke,
weight: 2,
opacity: 0.9,
fill: false,
}).addTo(this.group);
} else {
this.measureBoundary.setLatLngs(this.latlngs.concat(latlng));
}
}
if (this.latlngs.length >= 2) {
if (!this.measureArea) {
this.measureArea = L.polygon(this.latlngs.concat(latlng), {
clickable: false,
stroke: false,
fillColor: Colors.fill,
fillOpacity: 0.2,
}).addTo(this.group);
} else {
this.measureArea.setLatLngs(this.latlngs.concat(latlng));
}
}
if (this.latlngs.length >= 3) {
if (this.acceptMarker) {
this.group.removeLayer(this.acceptMarker);
this.acceptMarker = null;
}
const onAccept = e => {
L.DomEvent.stop(e);
this.confirmPolygon();
return false;
};
let acceptLatlng = this.latlngs[0];
this.acceptMarker = L.marker(acceptLatlng, {
icon: L.icon({
iconUrl: `/static/app/img/accept.png`,
iconSize: [20, 20],
iconAnchor: [10, 10],
className: "map-preview-accept-button",
}),
zIndexOffset: 99999
}).addTo(this.group)
.on("click", onAccept)
.on("contextmenu", onAccept);
}
};
confirmPolygon = () => {
if (this.latlngs.length >= 3){
const popupContainer = L.DomUtil.create('div');
popupContainer.className = "map-preview-delete";
const deleteLink = L.DomUtil.create('a');
deleteLink.href = "javascript:void(0)";
deleteLink.innerHTML = `<i class="fa fa-trash"></i> ${_("Delete")}`;
deleteLink.onclick = (e) => {
L.DomEvent.stop(e);
if (this.polygon){
this.group.removeLayer(this.polygon);
this.polygon = null;
}
};
popupContainer.appendChild(deleteLink);
this.polygon = L.polygon(this.latlngs, {
clickable: true,
weight: 3,
opacity: 0.9,
color: "#ffa716",
fillColor: "#ffa716",
fillOpacity: 0.2
}).bindPopup(popupContainer).addTo(this.group);
}
this.toggleCrop();
}
uniqueLatLonPush = latlng => {
if (this.latlngs.length === 0) this.latlngs.push(latlng);
else{
const last = this.latlngs[this.latlngs.length - 1];
if (last.lat !== latlng.lat && last.lng !== latlng.lng) this.latlngs.push(latlng);
}
};
handleMarkerDblClick = e => {
if (this.latlngs.length >= 2){
const latlng = this.map.mouseEventToLatLng(e.originalEvent);
this.uniqueLatLonPush(latlng);
this.confirmPolygon();
}
}
handleMarkerMove = e => {
const latlng = this.map.mouseEventToLatLng(e.originalEvent);
let lls = this.latlngs.concat(latlng);
lls.push(lls[0]);
if (this.measureBoundary) {
this.measureBoundary.setLatLngs(lls);
}
if (this.measureArea) {
this.measureArea.setLatLngs(lls);
}
}
handleMarkerContextMenu = e => {
if (this.latlngs.length >= 2){
const latlng = this.map.mouseEventToLatLng(e.originalEvent);
this.uniqueLatLonPush(latlng);
this.confirmPolygon();
}
return false;
}
onMapMove = () => {
if (this.captureMarker) this.captureMarker.setLatLng(this.map.getCenter());
};
onMapResize = () => {
if (this.captureMarker) this.captureMarker.setIcon(L.divIcon({
iconSize: this._map.getSize().multiplyBy(2)
}));
}
download = format => {
let output = "";
let filename = `images.${format}`;
@ -288,7 +489,7 @@ _('Example:'),
{this.state.error === "" ?
<div className="crop-control">
<button ref={(domNode) => {this.cropButton = domNode; }} type="button" onClick={this.toggleCrop} className={"btn btn-sm " + (this.state.cropping ? "btn-default" : "btn-secondary")} title={_("Set Crop Area (optional)")}>
<button ref={(domNode) => {this.cropButton = domNode; }} type="button" onClick={this.toggleCrop} className={"btn btn-sm " + (this.state.cropping ? "btn-default" : "btn-secondary")} title={_("Set Reconstruction Area (optional)")}>
<i className="fa fa-crop-alt"></i>
</button>
</div>

Wyświetl plik

@ -31,8 +31,25 @@
}
.leaflet-control-layers-expanded{
.leaflet-control-layers-base{
overflow: hidden;
}
height: 200px;
overflow: hidden;
}
.map-preview-marker-layer{
&:hover{
cursor: crosshair;
}
}
.map-preview-accept-button{
&:hover{
cursor: pointer;
}
}
.map-preview-delete{
min-width: 70px;
}
}