DebasishDhal99 commited on
Commit
1d6d0dd
·
1 Parent(s): c2a5a36

Add option for scientific/normal numerical representations

Browse files
frontend/src/components/Map.js CHANGED
@@ -68,6 +68,8 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
68
  const [polygonArea, setPolygonArea] = useState(null);
69
  const [areaUnit, setAreaUnit] = useState('sqm'); // 'sqm', 'sqkm', 'ha', 'acres', 'sqmi'
70
 
 
 
71
  const handleMouseDown = (e) => {
72
  isDragging.current = true;
73
  startX.current = e.clientX;
@@ -434,7 +436,12 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
434
  boxShadow: 'none',
435
  padding: 0
436
  }}>
437
- {geoDistance.toFixed(2)} {geoUnit}
 
 
 
 
 
438
  </span>
439
  </Tooltip>
440
  )}
@@ -461,7 +468,7 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
461
  icon={L.divIcon({
462
  className: 'area-label',
463
  html: polygonArea !== null
464
- ? `<div style="background:rgba(255,255,255,0.8);padding:2px 6px;border-radius:4px;color:#1976d2;font-weight:600;">${formatArea(polygonArea, areaUnit)}</div>`
465
  : '',
466
  iconSize: [100, 24],
467
  iconAnchor: [50, 12]
@@ -619,9 +626,23 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
619
  <option value="mi">Miles</option>
620
  </select>
621
  </div>
 
 
 
 
 
 
 
 
 
 
 
622
  {geoDistance !== null && (
623
  <div style={{ fontSize: 20, fontWeight: 600, color: '#1976d2' }}>
624
- {geoDistance.toFixed(2)} {geoUnit}
 
 
 
625
  </div>
626
  )}
627
  <button
@@ -668,7 +689,7 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
668
  </div>
669
  {polygonArea !== null && (
670
  <div style={{ fontSize: 20, fontWeight: 600, color: '#1976d2' }}>
671
- {formatArea(polygonArea, areaUnit)}
672
  </div>
673
  )}
674
  <button
@@ -703,6 +724,17 @@ const Map = ( { onMapClick, searchQuery, contentType } ) => {
703
  <option value="mi2">mi²</option>
704
  </select>
705
  </div>
 
 
 
 
 
 
 
 
 
 
 
706
  </>
707
  )}
708
  </div>
 
68
  const [polygonArea, setPolygonArea] = useState(null);
69
  const [areaUnit, setAreaUnit] = useState('sqm'); // 'sqm', 'sqkm', 'ha', 'acres', 'sqmi'
70
 
71
+ const [numberFormat, setNumberFormat] = useState('normal'); // 'normal' | 'scientific'
72
+
73
  const handleMouseDown = (e) => {
74
  isDragging.current = true;
75
  startX.current = e.clientX;
 
436
  boxShadow: 'none',
437
  padding: 0
438
  }}>
439
+ {geoDistance !== null
440
+ ? (numberFormat === 'scientific'
441
+ ? geoDistance.toExponential(2)
442
+ : geoDistance.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })
443
+ ) + ' ' + geoUnit
444
+ : ''}
445
  </span>
446
  </Tooltip>
447
  )}
 
468
  icon={L.divIcon({
469
  className: 'area-label',
470
  html: polygonArea !== null
471
+ ? `<div style="background:rgba(255,255,255,0.8);padding:2px 6px;border-radius:4px;color:#1976d2;font-weight:600;">${formatArea(polygonArea, areaUnit, numberFormat)}</div>`
472
  : '',
473
  iconSize: [100, 24],
474
  iconAnchor: [50, 12]
 
626
  <option value="mi">Miles</option>
627
  </select>
628
  </div>
629
+ <div>
630
+ <label style={{ fontWeight: 500, marginRight: 8 }}>Number format:</label>
631
+ <select
632
+ value={numberFormat}
633
+ onChange={e => setNumberFormat(e.target.value)}
634
+ style={{ padding: '4px 8px', borderRadius: 4, border: '1px solid #ccc' }}
635
+ >
636
+ <option value="normal">Normal</option>
637
+ <option value="scientific">Scientific</option>
638
+ </select>
639
+ </div>
640
  {geoDistance !== null && (
641
  <div style={{ fontSize: 20, fontWeight: 600, color: '#1976d2' }}>
642
+ {numberFormat === 'scientific'
643
+ ? geoDistance.toExponential(2)
644
+ : geoDistance.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })
645
+ }
646
  </div>
647
  )}
648
  <button
 
689
  </div>
690
  {polygonArea !== null && (
691
  <div style={{ fontSize: 20, fontWeight: 600, color: '#1976d2' }}>
692
+ {formatArea(polygonArea, areaUnit, numberFormat)}
693
  </div>
694
  )}
695
  <button
 
724
  <option value="mi2">mi²</option>
725
  </select>
726
  </div>
727
+ <div>
728
+ <label style={{ fontWeight: 500, marginRight: 8 }}>Number format:</label>
729
+ <select
730
+ value={numberFormat}
731
+ onChange={e => setNumberFormat(e.target.value)}
732
+ style={{ padding: '4px 8px', borderRadius: 4, border: '1px solid #ccc' }}
733
+ >
734
+ <option value="normal">Normal</option>
735
+ <option value="scientific">Scientific</option>
736
+ </select>
737
+ </div>
738
  </>
739
  )}
740
  </div>
frontend/src/utils/mapUtils.js CHANGED
@@ -110,25 +110,31 @@ function getPolygonCentroid(points) {
110
  return [x / n, y / n];
111
  }
112
 
113
- function formatArea(area, unit = 'sqm') {
114
 
115
  if (typeof area !== 'number' || isNaN(area)) {
116
  return 'Invalid area';
117
  }
118
-
119
  switch (unit) {
120
  case "km2":
121
- return (area / 1e6).toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }) + ' km²';
 
122
  case "ha":
123
- return (area / 1e4).toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }) + ' ha';
 
124
  case "sqm":
125
- return area.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }) + ' m²';
 
126
  case "acres":
127
- return (area / 4046.8564224).toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }) + ' acres';
 
128
  case "mi2":
129
- return (area / 2589988.110336).toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 }) + ' sq mi';
 
130
  default:
131
- return area.toFixed(2).toLocaleString() + ' m²'; // Default
 
132
  }
133
  }
134
 
 
110
  return [x / n, y / n];
111
  }
112
 
113
+ function formatArea(area, unit = 'sqm', format = "normal") {
114
 
115
  if (typeof area !== 'number' || isNaN(area)) {
116
  return 'Invalid area';
117
  }
118
+ let value;
119
  switch (unit) {
120
  case "km2":
121
+ value = area / 1e6;
122
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' km²';
123
  case "ha":
124
+ value = area / 1e4;
125
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' ha';
126
  case "sqm":
127
+ value = area;
128
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' m²';
129
  case "acres":
130
+ value = area / 4046.8564224;
131
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' acres';
132
  case "mi2":
133
+ value = area / 2589988.110336;
134
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' mi²';
135
  default:
136
+ value = area;
137
+ return (format === "scientific" ? value.toExponential(2) : value.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 })) + ' m²';
138
  }
139
  }
140