zh4rif commited on
Commit
d2a7bbf
·
verified ·
1 Parent(s): 9242be3

Update index.html

Browse files
Files changed (1) hide show
  1. index.html +743 -10
index.html CHANGED
@@ -1,13 +1,746 @@
1
  <!DOCTYPE html>
2
- <html lang="">
3
- <head>
4
  <meta charset="UTF-8">
5
- <link rel="icon" href="/favicon.ico">
6
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
7
- <title>Vite App</title>
8
- </head>
9
- <body>
10
- <div id="app"></div>
11
- <script type="module" src="/src/main.ts"></script>
12
- </body>
13
- </html>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
  <meta charset="UTF-8">
 
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Palm Monitor - Geospatial Intelligence Platform</title>
7
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css" />
8
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" />
9
+ <link rel="stylesheet" href="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.css" />
10
+
11
+ <style>
12
+ body {
13
+ font-family: Arial, sans-serif;
14
+ margin: 0;
15
+ padding: 0;
16
+ overflow-x: hidden;
17
+ }
18
+
19
+ .header {
20
+ background: #006838;
21
+ backdrop-filter: blur(10px);
22
+ color: white;
23
+ padding: 10px 25px;
24
+ display: flex;
25
+ justify-content: space-between;
26
+ align-items: center;
27
+ box-shadow: 0 4px 20px rgba(0,0,0,0.3);
28
+ position: relative;
29
+ z-index: 1000;
30
+ }
31
+
32
+ .logo {
33
+ display: flex;
34
+ align-items: center;
35
+ gap: 10px;
36
+ }
37
+
38
+ .user-info {
39
+ display: flex;
40
+ align-items: center;
41
+ gap: 15px;
42
+ }
43
+
44
+ .status-indicator {
45
+ display: flex;
46
+ align-items: center;
47
+ gap: 5px;
48
+ font-size: 14px;
49
+ }
50
+
51
+ .status-dot {
52
+ width: 8px;
53
+ height: 8px;
54
+ background: #27ae60;
55
+ border-radius: 50%;
56
+ animation: pulse 2s infinite;
57
+ }
58
+
59
+ @keyframes pulse {
60
+ 0% { opacity: 1; }
61
+ 50% { opacity: 0.5; }
62
+ 100% { opacity: 1; }
63
+ }
64
+
65
+ .main-container {
66
+ display: flex;
67
+ height: calc(100vh - 90px);
68
+ position: relative;
69
+ }
70
+
71
+ .sidebar {
72
+ width: 250px;
73
+ background: #f8f9fa;
74
+ border-right: 1px solid #ddd;
75
+ padding: 20px;
76
+ overflow-y: auto;
77
+ box-shadow: 2px 0 5px rgba(0,0,0,0.1);
78
+ z-index: 999;
79
+ }
80
+
81
+ .tool-group {
82
+ margin-bottom: 25px;
83
+ }
84
+
85
+ .tool-group h3 {
86
+ color: #2c3e50;
87
+ margin-bottom: 15px;
88
+ font-size: 16px;
89
+ display: flex;
90
+ align-items: center;
91
+ gap: 8px;
92
+ }
93
+
94
+ .tool-btn {
95
+ display: flex;
96
+ align-items: center;
97
+ gap: 10px;
98
+ width: 100%;
99
+ padding: 12px 15px;
100
+ margin-bottom: 8px;
101
+ border: 1px solid #ddd;
102
+ background: white;
103
+ border-radius: 6px;
104
+ cursor: pointer;
105
+ transition: all 0.3s ease;
106
+ font-size: 14px;
107
+ text-align: left;
108
+ }
109
+
110
+ .tool-btn:hover {
111
+ background: #e3f2fd;
112
+ border-color: #2196f3;
113
+ transform: translateY(-1px);
114
+ }
115
+
116
+ .tool-btn.active {
117
+ background: #2196f3;
118
+ color: white;
119
+ border-color: #2196f3;
120
+ }
121
+
122
+ .tool-btn i {
123
+ width: 16px;
124
+ text-align: center;
125
+ }
126
+
127
+ .file-input-wrapper {
128
+ display: flex;
129
+ flex-direction: column;
130
+ gap: 10px;
131
+ margin-top: 10px;
132
+ }
133
+
134
+ .file-input-wrapper input[type="file"] {
135
+ padding: 8px;
136
+ border: 1px solid #ddd;
137
+ border-radius: 4px;
138
+ font-size: 12px;
139
+ }
140
+
141
+ .export-buttons {
142
+ display: flex;
143
+ flex-direction: column;
144
+ gap: 5px;
145
+ margin-top: 10px;
146
+ }
147
+
148
+ .export-btn {
149
+ padding: 8px 12px;
150
+ background: #3498db;
151
+ color: white;
152
+ border: none;
153
+ border-radius: 4px;
154
+ cursor: pointer;
155
+ font-size: 12px;
156
+ transition: background 0.3s ease;
157
+ }
158
+
159
+ .export-btn:hover {
160
+ background: #2980b9;
161
+ }
162
+
163
+ #map-container {
164
+ flex: 1;
165
+ position: relative;
166
+ }
167
+
168
+ #map {
169
+ height: 100%;
170
+ width: 100%;
171
+ }
172
+
173
+ #infoForm {
174
+ display: none;
175
+ padding: 20px;
176
+ background: white;
177
+ border-top: 2px solid #3498db;
178
+ box-shadow: 0 -2px 10px rgba(0,0,0,0.1);
179
+ position: absolute;
180
+ bottom: 0;
181
+ left: 0;
182
+ right: 0;
183
+ z-index: 1000;
184
+ max-height: 300px;
185
+ overflow-y: auto;
186
+ }
187
+
188
+ .form-header {
189
+ display: flex;
190
+ justify-content: space-between;
191
+ align-items: center;
192
+ margin-bottom: 15px;
193
+ }
194
+
195
+ .close-btn {
196
+ background: none;
197
+ border: none;
198
+ font-size: 18px;
199
+ cursor: pointer;
200
+ color: #666;
201
+ }
202
+
203
+ .close-btn:hover {
204
+ color: #000;
205
+ }
206
+
207
+ .form-grid {
208
+ display: grid;
209
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
210
+ gap: 12px;
211
+ margin-bottom: 15px;
212
+ }
213
+
214
+ .form-grid input {
215
+ padding: 8px 12px;
216
+ font-size: 14px;
217
+ border: 1px solid #ddd;
218
+ border-radius: 4px;
219
+ width: 100%;
220
+ box-sizing: border-box;
221
+ }
222
+
223
+ .form-grid input:focus {
224
+ outline: none;
225
+ border-color: #3498db;
226
+ box-shadow: 0 0 0 2px rgba(52, 152, 219, 0.2);
227
+ }
228
+
229
+ .form-actions {
230
+ display: flex;
231
+ gap: 10px;
232
+ flex-wrap: wrap;
233
+ }
234
+
235
+ .form-actions button {
236
+ padding: 10px 20px;
237
+ font-size: 14px;
238
+ border: none;
239
+ border-radius: 4px;
240
+ cursor: pointer;
241
+ transition: all 0.3s ease;
242
+ }
243
+
244
+ .form-actions button:first-child {
245
+ background: #27ae60;
246
+ color: white;
247
+ }
248
+
249
+ .form-actions button:first-child:hover {
250
+ background: #219a52;
251
+ }
252
+
253
+ .form-actions button:last-child {
254
+ background: #3498db;
255
+ color: white;
256
+ }
257
+
258
+ .form-actions button:last-child:hover {
259
+ background: #2980b9;
260
+ }
261
+
262
+ h3 {
263
+ margin-bottom: 15px;
264
+ color: #2c3e50;
265
+ }
266
+
267
+ .btn {
268
+ padding: 5px 10px;
269
+ margin: 2px;
270
+ border: none;
271
+ border-radius: 3px;
272
+ cursor: pointer;
273
+ font-size: 12px;
274
+ }
275
+
276
+ .btn:hover {
277
+ opacity: 0.8;
278
+ }
279
+
280
+ /* Responsive design */
281
+ @media (max-width: 768px) {
282
+ .sidebar {
283
+ width: 250px;
284
+ }
285
+
286
+ .form-grid {
287
+ grid-template-columns: 1fr;
288
+ }
289
+ }
290
+
291
+ @media (max-width: 600px) {
292
+ .main-container {
293
+ flex-direction: column;
294
+ }
295
+
296
+ .sidebar {
297
+ width: 100%;
298
+ height: 200px;
299
+ border-right: none;
300
+ border-bottom: 1px solid #ddd;
301
+ }
302
+
303
+ #map-container {
304
+ height: calc(100vh - 290px);
305
+ }
306
+ }
307
+ .nav-button {
308
+ width: 90%;
309
+ padding: 12px 15px;
310
+ margin: 5px 0;
311
+ border: none;
312
+ background: linear-gradient(135deg, #006838 0%, #A1B593 100%);
313
+ color: white;
314
+ border-radius: 8px;
315
+ cursor: pointer;
316
+ transition: all 0.3s ease;
317
+ display: flex;
318
+ align-items: center;
319
+ gap: 10px;
320
+ font-size: 14px;
321
+ }
322
+
323
+ .nav-button:hover {
324
+ background-color: #fcfffc;
325
+ }
326
+ </style>
327
+ </head>
328
+ <body>
329
+ <div class="header">
330
+ <div class="logo">
331
+ <img src="https://images.squarespace-cdn.com/content/v1/604db3a6dad32a12b2415387/1636475927545-PK57PVLIB7AEKX1AJQJ8/Logo_MSPO_2020.png" alt="MSPO Logo" style="height: 60px;">
332
+ <div>
333
+ <span style="font-weight: bold;">MSPO-Palm Monitor</span><br>
334
+ <span style="font-size: 12px; opacity: 0.7;">Powered by Uzma Digital Earth</span>
335
+ </div>
336
+ </div>
337
+
338
+ <div class="user-info">
339
+ <div class="status-indicator">
340
+ <div class="status-dot"></div>
341
+ <span>Live Monitoring</span>
342
+ </div>
343
+ <i class="fas fa-user-circle" style="font-size: 24px;"></i>
344
+ </div>
345
+ </div>
346
+
347
+ <div class="main-container">
348
+ <div class="sidebar">
349
+ <div class="tool-group">
350
+ <h3><i class="fas fa-satellite"></i> Imagery</h3>
351
+ <button class="tool-btn active" onclick="toggleLayer('satellite')">
352
+ <i class="fas fa-globe"></i> High-Res Satellite
353
+ </button>
354
+ <button class="tool-btn" onclick="toggleLayer('terrain')">
355
+ <i class="fas fa-mountain"></i> Topographic Data
356
+ </button>
357
+ <button class="tool-btn" onclick="toggleLayer('ndvi')">
358
+ <i class="fas fa-seedling"></i> NDVI Analysis
359
+ </button>
360
+ <button class="tool-btn" onclick="requestNewImagery()">
361
+ <i class="fas fa-refresh"></i> Request Update
362
+ </button>
363
+
364
+ <button class="tool-btn" onclick="window.location.href='split_panel_map.html'">Deforestation Map</button>
365
+
366
+ <i class="fas fa-refresh"></i>
367
+ </button>
368
+ </div>
369
+
370
+ <div class="tool-group">
371
+ <h3><i class="fas fa-chart-line"></i> Analysis</h3>
372
+ <button class="tool-btn" onclick="runSpatialAnalysis()">
373
+ <i class="fas fa-calculator"></i> Spatial Analysis
374
+ </button>
375
+ <button class="tool-btn" onclick="generateReport()">
376
+ <i class="fas fa-file-alt"></i> Generate Report
377
+ </button>
378
+ <button class="tool-btn" onclick="trendAnalysis()">
379
+ <i class="fas fa-trending-up"></i> Trend Analysis
380
+ </button>
381
+ </div>
382
+
383
+ <div class="tool-group">
384
+ <h3><i class="fas fa-upload"></i> Import/Export Data</h3>
385
+ <div class="file-input-wrapper">
386
+ <input type="file" id="fileInput" accept=".geojson,.json" onchange="handleFileImport(event)" />
387
+ <div class="export-buttons">
388
+ <button class="export-btn" onclick="exportData('geojson')">
389
+ <i class="fas fa-download"></i> Export GeoJSON
390
+ </button>
391
+ <button class="export-btn" onclick="exportData('shapefile')">
392
+ <i class="fas fa-download"></i> Export Shapefile
393
+ </button>
394
+ <button class="export-btn" onclick="exportData('csv')">
395
+ <i class="fas fa-download"></i> Export CSV
396
+ </button>
397
+ <button class="export-btn" onclick="exportData('report')">
398
+ <i class="fas fa-file-pdf"></i> Generate Report
399
+ </button>
400
+ </div>
401
+ </div>
402
+ </div>
403
+ </div>
404
+
405
+ <div id="map-container">
406
+ <div id="map"></div>
407
+
408
+ <div id="infoForm">
409
+ <div class="form-header">
410
+ <h3>Polygon Info</h3>
411
+ <button class="close-btn" onclick="closeInfoForm()">
412
+ <i class="fas fa-times"></i>
413
+ </button>
414
+ </div>
415
+ <div class="form-grid">
416
+ <input id="license" placeholder="LICENSE NO." />
417
+ <input id="name" placeholder="SMALLHOLDER NAME" />
418
+ <input id="state" placeholder="STATE" />
419
+ <input id="district" placeholder="DISTRICT" />
420
+ <input id="subdistrict" placeholder="SUBDISTRICT" />
421
+ <input id="spocName" placeholder="SPOC NAME" />
422
+ <input id="spocCode" placeholder="SPOC CODE" />
423
+ <input id="lotNo" placeholder="LOT NO." />
424
+ <input id="certified" placeholder="CERTIFIED AREA (HA)" />
425
+ <input id="planted" placeholder="PLANTED AREA (HA)" />
426
+ <input id="latitude" placeholder="LATITUDE" readonly />
427
+ <input id="longitude" placeholder="LONGITUDE" readonly />
428
+ <input id="mspo" placeholder="MSPO CERTIFICATION" />
429
+ <input id="land" placeholder="LAND TITLE" />
430
+ <input id="shapeLength" placeholder="Shape_Length" />
431
+ <input id="shapeArea" placeholder="Shape_Area" />
432
+ </div>
433
+ <div class="form-actions">
434
+ <button onclick="saveInfo()">Save Info</button>
435
+ <button onclick="exportGeoJSON()">Download GeoJSON</button>
436
+ </div>
437
+ </div>
438
+ </div>
439
+ </div>
440
+
441
+ <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
442
+ <script src="https://unpkg.com/leaflet-draw@1.0.4/dist/leaflet.draw.js"></script>
443
+
444
+ <script>
445
+ const map = L.map('map').setView([4.4286, 102.0581], 12);
446
+
447
+ let baseLayers = {
448
+ satellite: L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
449
+ attribution: 'Esri, DigitalGlobe, GeoEye, Earthstar Geographics'
450
+ }),
451
+ terrain: L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Topo_Map/MapServer/tile/{z}/{y}/{x}', {
452
+ attribution: 'Esri, DeLorme, NAVTEQ'
453
+ }),
454
+ osm: L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
455
+ attribution: 'OpenStreetMap contributors'
456
+ })
457
+ };
458
+
459
+ baseLayers.satellite.addTo(map);
460
+
461
+ const drawnItems = new L.FeatureGroup();
462
+ map.addLayer(drawnItems);
463
+
464
+ const drawControl = new L.Control.Draw({
465
+ edit: { featureGroup: drawnItems },
466
+ draw: {
467
+ polygon: true,
468
+ polyline: true,
469
+ rectangle: true,
470
+ circle: true,
471
+ marker: true,
472
+ circlemarker: true
473
+ }
474
+ });
475
+ map.addControl(drawControl);
476
+
477
+ let currentLayer = null;
478
+ let currentCircle = null;
479
+ const geojsonFeatures = [];
480
+
481
+ map.on(L.Draw.Event.CREATED, function (e) {
482
+ const layer = e.layer;
483
+ const type = e.layerType;
484
+
485
+ drawnItems.addLayer(layer);
486
+
487
+ if (type === 'circle') {
488
+ currentCircle = layer;
489
+ const center = layer.getLatLng();
490
+ const radius = layer.getRadius();
491
+
492
+ layer.bindPopup(`
493
+ <strong>New Circle</strong><br>
494
+ Center: ${center.lat.toFixed(6)}, ${center.lng.toFixed(6)}<br>
495
+ Radius: ${(radius/1000).toFixed(2)} km<br>
496
+ <button onclick="analyzePolygon()" class="btn" style="background: #3498db; color: white;">Analyze</button>
497
+ <button onclick="deleteShape()" class="btn" style="background: #e74c3c; color: white;">Delete</button>
498
+ `);
499
+ } else if (type === 'marker') {
500
+ const latlng = layer.getLatLng();
501
+ layer.bindPopup(`
502
+ <strong>Marker</strong><br>
503
+ Location: ${latlng.lat.toFixed(6)}, ${latlng.lng.toFixed(6)}<br>
504
+ <button onclick="deleteShape()" class="btn" style="background: #e74c3c; color: white;">Delete</button>
505
+ `);
506
+ } else {
507
+ currentLayer = layer;
508
+ const center = layer.getBounds().getCenter();
509
+ document.getElementById('latitude').value = center.lat.toFixed(10);
510
+ document.getElementById('longitude').value = center.lng.toFixed(10);
511
+
512
+ const geojson = layer.toGeoJSON();
513
+ if (geojson.geometry.coordinates && geojson.geometry.coordinates[0]) {
514
+ const coords = geojson.geometry.coordinates[0];
515
+ document.getElementById('shapeLength').value = (coords.length * 0.0001).toFixed(6);
516
+ document.getElementById('shapeArea').value = (Math.random() * 1e-6).toFixed(12);
517
+ }
518
+
519
+ document.getElementById('infoForm').style.display = 'block';
520
+ }
521
+ });
522
+
523
+ // Delete shape function
524
+ function deleteShape() {
525
+ const popup = map._popup;
526
+ if (popup && popup._source) {
527
+ const layer = popup._source;
528
+ drawnItems.removeLayer(layer);
529
+ map.closePopup();
530
+ }
531
+ }
532
+
533
+ // Analyze polygon function
534
+ function analyzePolygon() {
535
+ showNotification('Analysis started for selected area...');
536
+ }
537
+
538
+ function toggleLayer(layerName) {
539
+ // Remove active class from all imagery buttons
540
+ document.querySelectorAll('.tool-group:first-child .tool-btn').forEach(btn => {
541
+ btn.classList.remove('active');
542
+ });
543
+
544
+ // Add active class to clicked button
545
+ event.target.classList.add('active');
546
+
547
+ switch(layerName) {
548
+ case 'satellite':
549
+ // Remove other layers
550
+ if (map.hasLayer(baseLayers.terrain)) {
551
+ map.removeLayer(baseLayers.terrain);
552
+ }
553
+ if (map.hasLayer(baseLayers.osm)) {
554
+ map.removeLayer(baseLayers.osm);
555
+ }
556
+ // Add satellite layer
557
+ if (!map.hasLayer(baseLayers.satellite)) {
558
+ baseLayers.satellite.addTo(map);
559
+ }
560
+ break;
561
+ case 'terrain':
562
+ // Remove other layers
563
+ if (map.hasLayer(baseLayers.satellite)) {
564
+ map.removeLayer(baseLayers.satellite);
565
+ }
566
+ if (map.hasLayer(baseLayers.osm)) {
567
+ map.removeLayer(baseLayers.osm);
568
+ }
569
+ // Add terrain layer
570
+ if (!map.hasLayer(baseLayers.terrain)) {
571
+ baseLayers.terrain.addTo(map);
572
+ }
573
+ break;
574
+ case 'ndvi':
575
+ showNotification('NDVI overlay activated');
576
+ break;
577
+ }
578
+ }
579
+
580
+ function requestNewImagery() {
581
+ showNotification('Requesting new imagery update...');
582
+ }
583
+
584
+ function runSpatialAnalysis() {
585
+ showNotification('Running spatial analysis...');
586
+ }
587
+
588
+ function generateReport() {
589
+ showNotification('Generating report...');
590
+ }
591
+
592
+ function trendAnalysis() {
593
+ showNotification('Performing trend analysis...');
594
+ }
595
+
596
+ function exportData(format) {
597
+ switch(format) {
598
+ case 'geojson':
599
+ exportGeoJSON();
600
+ break;
601
+ case 'shapefile':
602
+ showNotification('Shapefile export functionality would be implemented here');
603
+ break;
604
+ case 'csv':
605
+ exportCSV();
606
+ break;
607
+ case 'report':
608
+ showNotification('Report generation functionality would be implemented here');
609
+ break;
610
+ }
611
+ }
612
+
613
+ function exportCSV() {
614
+ if (geojsonFeatures.length === 0) {
615
+ showNotification('No data to export');
616
+ return;
617
+ }
618
+
619
+ const headers = Object.keys(geojsonFeatures[0].properties);
620
+ const csvContent = [
621
+ headers.join(','),
622
+ ...geojsonFeatures.map(feature =>
623
+ headers.map(header => feature.properties[header] || '').join(',')
624
+ )
625
+ ].join('\n');
626
+
627
+ const blob = new Blob([csvContent], { type: 'text/csv' });
628
+ const url = window.URL.createObjectURL(blob);
629
+ const a = document.createElement('a');
630
+ a.href = url;
631
+ a.download = 'polygons.csv';
632
+ document.body.appendChild(a);
633
+ a.click();
634
+ document.body.removeChild(a);
635
+ window.URL.revokeObjectURL(url);
636
+ }
637
+
638
+ function showNotification(message) {
639
+ alert(message);
640
+ }
641
+
642
+ function closeInfoForm() {
643
+ document.getElementById('infoForm').style.display = 'none';
644
+ // Clear form
645
+ document.querySelectorAll('#infoForm input').forEach(input => {
646
+ if (!input.readOnly) {
647
+ input.value = '';
648
+ }
649
+ });
650
+ currentLayer = null;
651
+ }
652
+
653
+ function saveInfo() {
654
+ if (!currentLayer) {
655
+ showNotification("Draw a polygon first.");
656
+ return;
657
+ }
658
+
659
+ const get = id => document.getElementById(id).value;
660
+
661
+ const properties = {
662
+ license: get('license'),
663
+ smallholder: get('name'),
664
+ state: get('state'),
665
+ district: get('district'),
666
+ subdistrict: get('subdistrict'),
667
+ spoc_name: get('spocName'),
668
+ spoc_code: get('spocCode'),
669
+ lot_no: get('lotNo'),
670
+ certified_area: get('certified'),
671
+ planted_area: get('planted'),
672
+ latitude: get('latitude'),
673
+ longitude: get('longitude'),
674
+ mspo: get('mspo'),
675
+ land_title: get('land'),
676
+ shape_length: get('shapeLength'),
677
+ shape_area: get('shapeArea')
678
+ };
679
+
680
+ const feature = currentLayer.toGeoJSON();
681
+ feature.properties = properties;
682
+ geojsonFeatures.push(feature);
683
+
684
+ const popupContent = Object.entries(properties)
685
+ .filter(([key, val]) => val)
686
+ .map(([key, val]) => `<b>${key.replace(/_/g, ' ').toUpperCase()}:</b> ${val}`)
687
+ .join("<br>");
688
+
689
+ currentLayer.bindPopup(popupContent).openPopup();
690
+
691
+ closeInfoForm();
692
+ showNotification('Polygon information saved successfully!');
693
+ }
694
+
695
+ function exportGeoJSON() {
696
+ if (geojsonFeatures.length === 0) {
697
+ showNotification('No data to export');
698
+ return;
699
+ }
700
+
701
+ const geojson = {
702
+ type: "FeatureCollection",
703
+ features: geojsonFeatures
704
+ };
705
+ const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(geojson, null, 2));
706
+ const dlAnchor = document.createElement('a');
707
+ dlAnchor.setAttribute("href", dataStr);
708
+ dlAnchor.setAttribute("download", "polygons.geojson");
709
+ document.body.appendChild(dlAnchor);
710
+ dlAnchor.click();
711
+ dlAnchor.remove();
712
+ showNotification('GeoJSON file exported successfully!');
713
+ }
714
+
715
+ function handleFileImport(event) {
716
+ const file = event.target.files[0];
717
+ if (file) {
718
+ const reader = new FileReader();
719
+ reader.onload = function(e) {
720
+ try {
721
+ const geojson = JSON.parse(e.target.result);
722
+ L.geoJSON(geojson, {
723
+ onEachFeature: function(feature, layer) {
724
+ drawnItems.addLayer(layer);
725
+ if (feature.properties) {
726
+ const popupContent = Object.entries(feature.properties)
727
+ .filter(([key, val]) => val)
728
+ .map(([key, val]) => `<b>${key.replace(/_/g, ' ').toUpperCase()}:</b> ${val}`)
729
+ .join("<br>");
730
+ layer.bindPopup(popupContent);
731
+ }
732
+ // Add to geojsonFeatures array
733
+ geojsonFeatures.push(feature);
734
+ }
735
+ });
736
+ showNotification('GeoJSON file imported successfully!');
737
+ } catch (error) {
738
+ showNotification('Error parsing GeoJSON file: ' + error.message);
739
+ }
740
+ };
741
+ reader.readAsText(file);
742
+ }
743
+ }
744
+ </script>
745
+ </body>
746
+ </html>