zhongrj
2025-11-25 b89962006164a462404b79a738bee8cbb6d7fe7e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import L from 'leaflet';
import './app.scss';
import 'leaflet-measure-ex/dist/leaflet-measure';
import 'leaflet-measure-ex/dist/leaflet-measure.css';
import MeasurePopup from './MeasurePopup';
import Utils from 'webodm/classes/Utils';
import ReactDOM from 'ReactDOM';
import React from 'React';
import $ from 'jquery';
import { _, get_format } from 'webodm/classes/gettext';
import { unitSystem } from 'webodm/classes/Units';
 
export default class App{
    constructor(map){
        this.map = map;
 
        const measure = L.control.measure({
          labels:{
            measureDistancesAndAreas: _('Measure volume, area and length'),
            areaMeasurement: _('Measurement'),
            measure: _("Measure"),
            createNewMeasurement: _("Create a new measurement"),
            startCreating: _("Start creating a measurement by adding points to the map"),
            finishMeasurement: _("Finish measurement"),
            lastPoint: _("Last point"),
            area: _("Area"),
            perimeter: _("Perimeter"),
            pointLocation: _("Point location"),
            linearMeasurement: _("Linear measurement"),
            pathDistance: _("Path distance"),
            centerOnArea: _("Center on this area"),
            centerOnLine: _("Center on this line"),
            centerOnLocation: _("Center on this location"),
            cancel: _("Cancel"),
            delete: _("Delete"),
            acres: _("Acres"),
            feet: _("Feet"),
            kilometers: _("Kilometers"),
            hectares: _("Hectares"),
            meters: _("Meters"),
            miles: _("Miles"),
            sqfeet: _("Sq Feet"),
            sqmeters: _("Sq Meters"),
            sqmiles: _("Sq Miles"),
            decPoint: get_format("DECIMAL_SEPARATOR"),
            thousandsSep: get_format("THOUSAND_SEPARATOR")
          },
          primaryLengthUnit: 'meters',
          secondaryLengthUnit: 'feet',
          primaryAreaUnit: 'sqmeters',
          secondaryAreaUnit: 'acres'
        }).addTo(map);
 
        // measure.options.labels.
 
        measure._getMeasurementDisplayStrings = measurement => {
          const us = unitSystem();
 
          return {
            lengthDisplay: us.length(measurement.length).toString(),
            areaDisplay: us.area(measurement.area).toString()
          };
        };
 
        const $btnExport = $(`<br/><a href='#' class='js-start start'>${_("Export Measurements")}</a>`);
        $btnExport.appendTo($(measure.$startPrompt).children("ul.tasks"));
        $btnExport.on('click', () => {
          const features = [];
          map.eachLayer(layer => {
            const mp = layer._measurePopup;
            if (mp){
              features.push(mp.getGeoJSON());
            }
          });
 
          const geoJSON = {
            type: "FeatureCollection",
            features: features
          };
 
          Utils.saveAs(JSON.stringify(geoJSON, null, 4), "measurements.geojson")
        });
 
        map.on('measurepopupshown', ({popupContainer, model, resultFeature}) => {
            // Only modify area popup, length popup is fine as default
            const $container = $("<div/>"),
                  $popup = $(popupContainer);
            
            if (model.area !== 0){
              // Erase measurements for area
              $popup.children("p").empty();
            }
            $popup.children("ul.tasks").before($container);
 
            ReactDOM.render(<MeasurePopup 
                                model={model}
                                resultFeature={resultFeature} 
                                map={map} />, $container.get(0));
        });
    }
}