Zeel commited on
Commit
5262418
·
verified ·
1 Parent(s): 5efc971

Upload folder using huggingface_hub

Browse files
.github/workflows/static.yml ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Simple workflow for deploying static content to GitHub Pages
2
+ name: Deploy static content to Pages
3
+
4
+ on:
5
+ # Runs on pushes targeting the default branch
6
+ push:
7
+ branches: ["main"]
8
+
9
+ # Allows you to run this workflow manually from the Actions tab
10
+ workflow_dispatch:
11
+
12
+ # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
13
+ permissions:
14
+ contents: read
15
+ pages: write
16
+ id-token: write
17
+
18
+ # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
19
+ # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
20
+ concurrency:
21
+ group: "pages"
22
+ cancel-in-progress: false
23
+
24
+ jobs:
25
+ # Single deploy job since we're just deploying
26
+ deploy:
27
+ environment:
28
+ name: github-pages
29
+ url: ${{ steps.deployment.outputs.page_url }}
30
+ runs-on: ubuntu-latest
31
+ steps:
32
+ - name: Checkout
33
+ uses: actions/checkout@v4
34
+ - name: Setup Pages
35
+ uses: actions/configure-pages@v5
36
+ - name: Upload artifact
37
+ uses: actions/upload-pages-artifact@v3
38
+ with:
39
+ # Upload entire repository
40
+ path: '.'
41
+ - name: Deploy to GitHub Pages
42
+ id: deployment
43
+ uses: actions/deploy-pages@v4
L.KML.js ADDED
@@ -0,0 +1,482 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /*!
2
+ Copyright (c) 2011-2015, Pavel Shramov, Bruno Bergot - MIT licence
3
+ */
4
+
5
+ L.KML = L.FeatureGroup.extend({
6
+
7
+ initialize: function (kml, kmlOptions) {
8
+ this._kml = kml;
9
+ this._layers = {};
10
+ this._kmlOptions = kmlOptions;
11
+
12
+ if (kml) {
13
+ this.addKML(kml, kmlOptions);
14
+ }
15
+ },
16
+
17
+ addKML: function (xml, kmlOptions) {
18
+ var layers = L.KML.parseKML(xml, kmlOptions);
19
+ if (!layers || !layers.length) return;
20
+ for (var i = 0; i < layers.length; i++) {
21
+ this.fire('addlayer', {
22
+ layer: layers[i]
23
+ });
24
+ this.addLayer(layers[i]);
25
+ }
26
+ this.latLngs = L.KML.getLatLngs(xml);
27
+ this.fire('loaded');
28
+ },
29
+
30
+ latLngs: []
31
+ });
32
+
33
+ L.Util.extend(L.KML, {
34
+
35
+ parseKML: function (xml, kmlOptions) {
36
+ var style = this.parseStyles(xml, kmlOptions);
37
+ this.parseStyleMap(xml, style);
38
+ var el = xml.getElementsByTagName('Folder');
39
+ var layers = [], l;
40
+ for (var i = 0; i < el.length; i++) {
41
+ if (!this._check_folder(el[i])) { continue; }
42
+ l = this.parseFolder(el[i], style);
43
+ if (l) { layers.push(l); }
44
+ }
45
+ el = xml.getElementsByTagName('Placemark');
46
+ for (var j = 0; j < el.length; j++) {
47
+ if (!this._check_folder(el[j])) { continue; }
48
+ l = this.parsePlacemark(el[j], xml, style);
49
+ if (l) { layers.push(l); }
50
+ }
51
+ el = xml.getElementsByTagName('GroundOverlay');
52
+ for (var k = 0; k < el.length; k++) {
53
+ l = this.parseGroundOverlay(el[k]);
54
+ if (l) { layers.push(l); }
55
+ }
56
+ return layers;
57
+ },
58
+
59
+ // Return false if e's first parent Folder is not [folder]
60
+ // - returns true if no parent Folders
61
+ _check_folder: function (e, folder) {
62
+ e = e.parentNode;
63
+ while (e && e.tagName !== 'Folder')
64
+ {
65
+ e = e.parentNode;
66
+ }
67
+ return !e || e === folder;
68
+ },
69
+
70
+ parseStyles: function (xml, kmlOptions) {
71
+ var styles = {};
72
+ var sl = xml.getElementsByTagName('Style');
73
+ for (var i=0, len=sl.length; i<len; i++) {
74
+ var style = this.parseStyle(sl[i], kmlOptions);
75
+ if (style) {
76
+ var styleName = '#' + style.id;
77
+ styles[styleName] = style;
78
+ }
79
+ }
80
+ return styles;
81
+ },
82
+
83
+ parseStyle: function (xml, kmlOptions) {
84
+ var style = {}, poptions = {}, ioptions = {}, el, id;
85
+
86
+ var attributes = {color: true, width: true, Icon: true, href: true, hotSpot: true};
87
+
88
+ function _parse (xml) {
89
+ var options = {};
90
+ for (var i = 0; i < xml.childNodes.length; i++) {
91
+ var e = xml.childNodes[i];
92
+ var key = e.tagName;
93
+ if (!attributes[key]) { continue; }
94
+ if (key === 'hotSpot')
95
+ {
96
+ for (var j = 0; j < e.attributes.length; j++) {
97
+ options[e.attributes[j].name] = e.attributes[j].nodeValue;
98
+ }
99
+ } else {
100
+ var value = (e.childNodes && e.childNodes.length) ? e.childNodes[0].nodeValue : null;
101
+ if(!value) {
102
+ continue;
103
+ }
104
+ if (key === 'color') {
105
+ options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
106
+ options.color = '#' + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
107
+ } else if (key === 'width') {
108
+ options.weight = parseInt(value);
109
+ } else if (key === 'Icon') {
110
+ ioptions = _parse(e);
111
+ if (ioptions.href) { options.href = ioptions.href; }
112
+ } else if (key === 'href') {
113
+ options.href = value;
114
+ }
115
+ }
116
+ }
117
+ return options;
118
+ }
119
+
120
+ el = xml.getElementsByTagName('LineStyle');
121
+ if (el && el[0]) { style = _parse(el[0]); }
122
+ el = xml.getElementsByTagName('PolyStyle');
123
+ if (el && el[0]) { poptions = _parse(el[0]); }
124
+ if (poptions.color) { style.fillColor = poptions.color; }
125
+ if (poptions.opacity) { style.fillOpacity = poptions.opacity; }
126
+ el = xml.getElementsByTagName('IconStyle');
127
+ if (el && el[0]) { ioptions = _parse(el[0]); }
128
+ if (ioptions.href) {
129
+ var iconOptions = {
130
+ iconUrl: ioptions.href,
131
+ shadowUrl: null,
132
+ anchorRef: {x: ioptions.x, y: ioptions.y},
133
+ anchorType: {x: ioptions.xunits, y: ioptions.yunits}
134
+ };
135
+
136
+ if (typeof kmlOptions === "object" && typeof kmlOptions.iconOptions === "object") {
137
+ L.Util.extend(iconOptions, kmlOptions.iconOptions);
138
+ }
139
+
140
+ style.icon = new L.KMLIcon(iconOptions);
141
+ }
142
+
143
+ id = xml.getAttribute('id');
144
+ if (id && style) {
145
+ style.id = id;
146
+ }
147
+
148
+ return style;
149
+ },
150
+
151
+ parseStyleMap: function (xml, existingStyles) {
152
+ var sl = xml.getElementsByTagName('StyleMap');
153
+
154
+ for (var i = 0; i < sl.length; i++) {
155
+ var e = sl[i], el;
156
+ var smKey, smStyleUrl;
157
+
158
+ el = e.getElementsByTagName('key');
159
+ if (el && el[0]) { smKey = el[0].textContent; }
160
+ el = e.getElementsByTagName('styleUrl');
161
+ if (el && el[0]) { smStyleUrl = el[0].textContent; }
162
+
163
+ if (smKey === 'normal')
164
+ {
165
+ existingStyles['#' + e.getAttribute('id')] = existingStyles[smStyleUrl];
166
+ }
167
+ }
168
+
169
+ return;
170
+ },
171
+
172
+ parseFolder: function (xml, style) {
173
+ var el, layers = [], l;
174
+ el = xml.getElementsByTagName('Folder');
175
+ for (var i = 0; i < el.length; i++) {
176
+ if (!this._check_folder(el[i], xml)) { continue; }
177
+ l = this.parseFolder(el[i], style);
178
+ if (l) { layers.push(l); }
179
+ }
180
+ el = xml.getElementsByTagName('Placemark');
181
+ for (var j = 0; j < el.length; j++) {
182
+ if (!this._check_folder(el[j], xml)) { continue; }
183
+ l = this.parsePlacemark(el[j], xml, style);
184
+ if (l) { layers.push(l); }
185
+ }
186
+ el = xml.getElementsByTagName('GroundOverlay');
187
+ for (var k = 0; k < el.length; k++) {
188
+ if (!this._check_folder(el[k], xml)) { continue; }
189
+ l = this.parseGroundOverlay(el[k]);
190
+ if (l) { layers.push(l); }
191
+ }
192
+ if (!layers.length) { return; }
193
+ if (layers.length === 1) {
194
+ l = layers[0];
195
+ } else {
196
+ l = new L.FeatureGroup(layers);
197
+ }
198
+ el = xml.getElementsByTagName('name');
199
+ if (el.length && el[0].childNodes.length) {
200
+ l.options.name = el[0].childNodes[0].nodeValue;
201
+ }
202
+ return l;
203
+ },
204
+
205
+ parsePlacemark: function (place, xml, style, options) {
206
+ var h, i, j, k, el, il, opts = options || {};
207
+
208
+ el = place.getElementsByTagName('styleUrl');
209
+ for (i = 0; i < el.length; i++) {
210
+ var url = el[i].childNodes[0].nodeValue;
211
+ for (var a in style[url]) {
212
+ opts[a] = style[url][a];
213
+ }
214
+ }
215
+
216
+ il = place.getElementsByTagName('Style')[0];
217
+ if (il) {
218
+ var inlineStyle = this.parseStyle(place);
219
+ if (inlineStyle) {
220
+ for (k in inlineStyle) {
221
+ opts[k] = inlineStyle[k];
222
+ }
223
+ }
224
+ }
225
+
226
+ var multi = ['MultiGeometry', 'MultiTrack', 'gx:MultiTrack'];
227
+ for (h in multi) {
228
+ el = place.getElementsByTagName(multi[h]);
229
+ for (i = 0; i < el.length; i++) {
230
+ var layer = this.parsePlacemark(el[i], xml, style, opts);
231
+ if (layer === undefined)
232
+ continue;
233
+ this.addPlacePopup(place, layer);
234
+ return layer;
235
+ }
236
+ }
237
+
238
+ var layers = [];
239
+
240
+ var parse = ['LineString', 'Polygon', 'Point', 'Track', 'gx:Track'];
241
+ for (j in parse) {
242
+ var tag = parse[j];
243
+ el = place.getElementsByTagName(tag);
244
+ for (i = 0; i < el.length; i++) {
245
+ var l = this['parse' + tag.replace(/gx:/, '')](el[i], xml, opts);
246
+ if (l) { layers.push(l); }
247
+ }
248
+ }
249
+
250
+ if (!layers.length) {
251
+ return;
252
+ }
253
+ var layer = layers[0];
254
+ if (layers.length > 1) {
255
+ layer = new L.FeatureGroup(layers);
256
+ }
257
+
258
+ this.addPlacePopup(place, layer);
259
+ return layer;
260
+ },
261
+
262
+ addPlacePopup: function(place, layer) {
263
+ var el, i, j, name, descr = '';
264
+ el = place.getElementsByTagName('name');
265
+ if (el.length && el[0].childNodes.length) {
266
+ name = el[0].childNodes[0].nodeValue;
267
+ }
268
+ el = place.getElementsByTagName('description');
269
+ for (i = 0; i < el.length; i++) {
270
+ for (j = 0; j < el[i].childNodes.length; j++) {
271
+ descr = descr + el[i].childNodes[j].nodeValue;
272
+ }
273
+ }
274
+
275
+ if (name) {
276
+ layer.bindPopup('<h2>' + name + '</h2>' + descr, { className: 'kml-popup'});
277
+ }
278
+ },
279
+
280
+ parseCoords: function (xml) {
281
+ var el = xml.getElementsByTagName('coordinates');
282
+ return this._read_coords(el[0]);
283
+ },
284
+
285
+ parseLineString: function (line, xml, options) {
286
+ var coords = this.parseCoords(line);
287
+ if (!coords.length) { return; }
288
+ return new L.Polyline(coords, options);
289
+ },
290
+
291
+ parseTrack: function (line, xml, options) {
292
+ var el = xml.getElementsByTagName('gx:coord');
293
+ if (el.length === 0) { el = xml.getElementsByTagName('coord'); }
294
+ var coords = [];
295
+ for (var j = 0; j < el.length; j++) {
296
+ coords = coords.concat(this._read_gxcoords(el[j]));
297
+ }
298
+ if (!coords.length) { return; }
299
+ return new L.Polyline(coords, options);
300
+ },
301
+
302
+ parsePoint: function (line, xml, options) {
303
+ var el = line.getElementsByTagName('coordinates');
304
+ if (!el.length) {
305
+ return;
306
+ }
307
+ var ll = el[0].childNodes[0].nodeValue.split(',');
308
+ return new L.KMLMarker(new L.LatLng(ll[1], ll[0]), options);
309
+ },
310
+
311
+ parsePolygon: function (line, xml, options) {
312
+ var el, polys = [], inner = [], i, coords;
313
+ el = line.getElementsByTagName('outerBoundaryIs');
314
+ for (i = 0; i < el.length; i++) {
315
+ coords = this.parseCoords(el[i]);
316
+ if (coords) {
317
+ polys.push(coords);
318
+ }
319
+ }
320
+ el = line.getElementsByTagName('innerBoundaryIs');
321
+ for (i = 0; i < el.length; i++) {
322
+ coords = this.parseCoords(el[i]);
323
+ if (coords) {
324
+ inner.push(coords);
325
+ }
326
+ }
327
+ if (!polys.length) {
328
+ return;
329
+ }
330
+ if (options.fillColor) {
331
+ options.fill = true;
332
+ }
333
+ if (polys.length === 1) {
334
+ return new L.Polygon(polys.concat(inner), options);
335
+ }
336
+ return new L.MultiPolygon(polys, options);
337
+ },
338
+
339
+ getLatLngs: function (xml) {
340
+ var el = xml.getElementsByTagName('coordinates');
341
+ var coords = [];
342
+ for (var j = 0; j < el.length; j++) {
343
+ // text might span many childNodes
344
+ coords = coords.concat(this._read_coords(el[j]));
345
+ }
346
+ return coords;
347
+ },
348
+
349
+ _read_coords: function (el) {
350
+ var text = '', coords = [], i;
351
+ for (i = 0; i < el.childNodes.length; i++) {
352
+ text = text + el.childNodes[i].nodeValue;
353
+ }
354
+ text = text.split(/[\s\n]+/);
355
+ for (i = 0; i < text.length; i++) {
356
+ var ll = text[i].split(',');
357
+ if (ll.length < 2) {
358
+ continue;
359
+ }
360
+ coords.push(new L.LatLng(ll[1], ll[0]));
361
+ }
362
+ return coords;
363
+ },
364
+
365
+ _read_gxcoords: function (el) {
366
+ var text = '', coords = [];
367
+ text = el.firstChild.nodeValue.split(' ');
368
+ coords.push(new L.LatLng(text[1], text[0]));
369
+ return coords;
370
+ },
371
+
372
+ parseGroundOverlay: function (xml) {
373
+ var latlonbox = xml.getElementsByTagName('LatLonBox')[0];
374
+ var bounds = new L.LatLngBounds(
375
+ [
376
+ latlonbox.getElementsByTagName('south')[0].childNodes[0].nodeValue,
377
+ latlonbox.getElementsByTagName('west')[0].childNodes[0].nodeValue
378
+ ],
379
+ [
380
+ latlonbox.getElementsByTagName('north')[0].childNodes[0].nodeValue,
381
+ latlonbox.getElementsByTagName('east')[0].childNodes[0].nodeValue
382
+ ]
383
+ );
384
+ var attributes = {Icon: true, href: true, color: true};
385
+ function _parse (xml) {
386
+ var options = {}, ioptions = {};
387
+ for (var i = 0; i < xml.childNodes.length; i++) {
388
+ var e = xml.childNodes[i];
389
+ var key = e.tagName;
390
+ if (!attributes[key]) { continue; }
391
+ var value = e.childNodes[0].nodeValue;
392
+ if (key === 'Icon') {
393
+ ioptions = _parse(e);
394
+ if (ioptions.href) { options.href = ioptions.href; }
395
+ } else if (key === 'href') {
396
+ options.href = value;
397
+ } else if (key === 'color') {
398
+ options.opacity = parseInt(value.substring(0, 2), 16) / 255.0;
399
+ options.color = '#' + value.substring(6, 8) + value.substring(4, 6) + value.substring(2, 4);
400
+ }
401
+ }
402
+ return options;
403
+ }
404
+ var options = {};
405
+ options = _parse(xml);
406
+ if (latlonbox.getElementsByTagName('rotation')[0] !== undefined) {
407
+ var rotation = latlonbox.getElementsByTagName('rotation')[0].childNodes[0].nodeValue;
408
+ options.rotation = parseFloat(rotation);
409
+ }
410
+ return new L.RotatedImageOverlay(options.href, bounds, {opacity: options.opacity, angle: options.rotation});
411
+ }
412
+
413
+ });
414
+
415
+ L.KMLIcon = L.Icon.extend({
416
+ options: {
417
+ iconSize: [32, 32],
418
+ iconAnchor: [16, 16],
419
+ },
420
+ _setIconStyles: function (img, name) {
421
+ L.Icon.prototype._setIconStyles.apply(this, [img, name]);
422
+ },
423
+ _createImg: function (src, el) {
424
+ el = el || document.createElement('img');
425
+ el.onload = this.applyCustomStyles.bind(this,el)
426
+ el.src = src;
427
+ return el;
428
+ },
429
+ applyCustomStyles: function(img) {
430
+ var options = this.options;
431
+ var width = options.iconSize[0];
432
+ var height = options.iconSize[1];
433
+
434
+ this.options.popupAnchor = [0,(-0.83*height)];
435
+ if (options.anchorType.x === 'fraction')
436
+ img.style.marginLeft = (-options.anchorRef.x * width) + 'px';
437
+ if (options.anchorType.y === 'fraction')
438
+ img.style.marginTop = ((-(1 - options.anchorRef.y) * height) + 1) + 'px';
439
+ if (options.anchorType.x === 'pixels')
440
+ img.style.marginLeft = (-options.anchorRef.x) + 'px';
441
+ if (options.anchorType.y === 'pixels')
442
+ img.style.marginTop = (options.anchorRef.y - height + 1) + 'px';
443
+ }
444
+ });
445
+
446
+
447
+ L.KMLMarker = L.Marker.extend({
448
+ options: {
449
+ icon: new L.KMLIcon.Default()
450
+ }
451
+ });
452
+
453
+ // Inspired by https://github.com/bbecquet/Leaflet.PolylineDecorator/tree/master/src
454
+ L.RotatedImageOverlay = L.ImageOverlay.extend({
455
+ options: {
456
+ angle: 0
457
+ },
458
+ _reset: function () {
459
+ L.ImageOverlay.prototype._reset.call(this);
460
+ this._rotate();
461
+ },
462
+ _animateZoom: function (e) {
463
+ L.ImageOverlay.prototype._animateZoom.call(this, e);
464
+ this._rotate();
465
+ },
466
+ _rotate: function () {
467
+ if (L.DomUtil.TRANSFORM) {
468
+ // use the CSS transform rule if available
469
+ this._image.style[L.DomUtil.TRANSFORM] += ' rotate(' + this.options.angle + 'deg)';
470
+ } else if (L.Browser.ie) {
471
+ // fallback for IE6, IE7, IE8
472
+ var rad = this.options.angle * (Math.PI / 180),
473
+ costheta = Math.cos(rad),
474
+ sintheta = Math.sin(rad);
475
+ this._image.style.filter += ' progid:DXImageTransform.Microsoft.Matrix(sizingMethod=\'auto expand\', M11=' +
476
+ costheta + ', M12=' + (-sintheta) + ', M21=' + sintheta + ', M22=' + costheta + ')';
477
+ }
478
+ },
479
+ getBounds: function () {
480
+ return this._bounds;
481
+ }
482
+ });
README.md CHANGED
@@ -1,12 +1 @@
1
- ---
2
- title: Bhuvan
3
- emoji: 🐨
4
- colorFrom: yellow
5
- colorTo: blue
6
- sdk: gradio
7
- sdk_version: 5.4.0
8
- app_file: app.py
9
- pinned: false
10
- ---
11
-
12
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
1
+ # bhuvan
 
 
 
 
 
 
 
 
 
 
 
data/Bhankhara-Df-11-he-5-2020-21.kml ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:kml="http://www.opengis.net/kml/2.2" xmlns:atom="http://www.w3.org/2005/Atom">
3
+ <Document>
4
+ <name>Bhankhara Df 11 he 5 2020-21</name>
5
+ <gx:CascadingStyle kml:id="__managed_style_2ECD90080C332BDE40E2">
6
+ <Style>
7
+ <IconStyle>
8
+ <scale>1.2</scale>
9
+ <Icon>
10
+ <href>https://earth.google.com/earth/rpc/cc/icon?color=1976d2&amp;id=2000&amp;scale=4</href>
11
+ </Icon>
12
+ <hotSpot x="64" y="128" xunits="pixels" yunits="insetPixels"/>
13
+ </IconStyle>
14
+ <LabelStyle>
15
+ </LabelStyle>
16
+ <LineStyle>
17
+ <color>ff2dc0fb</color>
18
+ <width>2.4389</width>
19
+ </LineStyle>
20
+ <PolyStyle>
21
+ <color>00ffffff</color>
22
+ </PolyStyle>
23
+ <BalloonStyle>
24
+ <displayMode>hide</displayMode>
25
+ </BalloonStyle>
26
+ </Style>
27
+ </gx:CascadingStyle>
28
+ <gx:CascadingStyle kml:id="__managed_style_175A38A9FB332BDE40E2">
29
+ <Style>
30
+ <IconStyle>
31
+ <Icon>
32
+ <href>https://earth.google.com/earth/rpc/cc/icon?color=1976d2&amp;id=2000&amp;scale=4</href>
33
+ </Icon>
34
+ <hotSpot x="64" y="128" xunits="pixels" yunits="insetPixels"/>
35
+ </IconStyle>
36
+ <LabelStyle>
37
+ </LabelStyle>
38
+ <LineStyle>
39
+ <color>ff2dc0fb</color>
40
+ <width>1.62594</width>
41
+ </LineStyle>
42
+ <PolyStyle>
43
+ <color>00ffffff</color>
44
+ </PolyStyle>
45
+ <BalloonStyle>
46
+ <displayMode>hide</displayMode>
47
+ </BalloonStyle>
48
+ </Style>
49
+ </gx:CascadingStyle>
50
+ <StyleMap id="__managed_style_02B2DF3F10332BDE40E2">
51
+ <Pair>
52
+ <key>normal</key>
53
+ <styleUrl>#__managed_style_175A38A9FB332BDE40E2</styleUrl>
54
+ </Pair>
55
+ <Pair>
56
+ <key>highlight</key>
57
+ <styleUrl>#__managed_style_2ECD90080C332BDE40E2</styleUrl>
58
+ </Pair>
59
+ </StyleMap>
60
+ <Placemark id="0CB71842DC32C34FCCDC">
61
+ <name>bhankhara Df </name>
62
+ <LookAt>
63
+ <longitude>73.23288329025303</longitude>
64
+ <latitude>23.92934021215672</latitude>
65
+ <altitude>351.5436929053654</altitude>
66
+ <heading>22.18919554855782</heading>
67
+ <tilt>0</tilt>
68
+ <gx:fovy>30.00004101</gx:fovy>
69
+ <range>1627.012775921321</range>
70
+ <altitudeMode>absolute</altitudeMode>
71
+ </LookAt>
72
+ <styleUrl>#__managed_style_02B2DF3F10332BDE40E2</styleUrl>
73
+ <Polygon>
74
+ <outerBoundaryIs>
75
+ <LinearRing>
76
+ <coordinates>
77
+ 73.23288020595453,23.92934920152165,0 73.2320424558106,23.9295414782706,0 73.23177030588151,23.9290796121952,0 73.23049283479376,23.92975711242018,0 73.2296710069635,23.93046123326063,0 73.2287325848189,23.92942606846368,0 73.23001098215263,23.92845402165482,0 73.23132082595696,23.92741616938989,0 73.23174863262777,23.92774125965506,0 73.23240516734252,23.92789815610602,0 73.23288020595453,23.92934920152165,0
78
+ </coordinates>
79
+ </LinearRing>
80
+ </outerBoundaryIs>
81
+ </Polygon>
82
+ </Placemark>
83
+ </Document>
84
+ </kml>
data/Bhankhara_Df_11_he_5_2020-21.geojson ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "type": "FeatureCollection",
3
+ "name": "Bhankhara Df 11 he 5 2020-21",
4
+ "crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:OGC:1.3:CRS84" } },
5
+ "features": [
6
+ { "type": "Feature", "properties": { "Name": "bhankhara Df " }, "geometry": { "type": "Polygon", "coordinates": [ [ [ 73.232880205954501, 23.9293492015216 ], [ 73.2320424558106, 23.9295414782706 ], [ 73.231770305881497, 23.929079612195199 ], [ 73.230492834793793, 23.929757112420202 ], [ 73.2296710069635, 23.930461233260601 ], [ 73.2287325848189, 23.929426068463702 ], [ 73.230010982152606, 23.928454021654801 ], [ 73.231320825956999, 23.9274161693899 ], [ 73.231748632627799, 23.9277412596551 ], [ 73.232405167342506, 23.927898156106 ], [ 73.232880205954501, 23.9293492015216 ] ] ] } }
7
+ ]
8
+ }
geojson.html ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <html>
2
+ <head>
3
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
4
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
5
+ <script src="https://unpkg.com/@turf/[email protected]/turf.min.js"></script>
6
+ <link rel="stylesheet" href="style.css"> <!-- Link to the external style.css file -->
7
+
8
+ </head>
9
+
10
+ <body>
11
+ <header>Interactive GeoJSON Map Viewer</header>
12
+
13
+ <div id="map"></div>
14
+
15
+ <div id="stats">
16
+ <h3>GeoJSON Statistics</h3>
17
+ <div class="stat-item">
18
+ <div class="stat-label"><i>📐</i> Area (sq meters):</div>
19
+ <div id="area_sqm" class="value">Loading...</div>
20
+ </div>
21
+ <div class="stat-item">
22
+ <div class="stat-label"><i>🌍</i> Area (hectares):</div>
23
+ <div id="area_hectares" class="value">Loading...</div>
24
+ </div>
25
+ <div class="stat-item">
26
+ <div class="stat-label"><i>📍</i> Centroid:</div>
27
+ <div id="centroid" class="value">Loading...</div>
28
+ </div>
29
+ <div class="stat-item">
30
+ <span class="stat-label"><i>Summary:</i></span>
31
+ <div class="value" id="summary">Loading...</div>
32
+ </div>
33
+ </div>
34
+
35
+ <footer>&copy; 2024 GeoJSON Map Viewer by Sustainability Lab IIT Gandhinagar</footer>
36
+ <script src="geostats.js"></script> <!-- Custom script for area and centroid calculations -->
37
+
38
+ <script type="text/javascript">
39
+ // Initialize the map
40
+ const map = L.map('map').setView([58.4, 43.0], 11);
41
+
42
+ // Add a base map layer
43
+ new L.TileLayer('http://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}').addTo(map);
44
+
45
+ // Function to load GeoJSON and calculate statistics
46
+ function loadGeoJSON(url) {
47
+ fetch(url)
48
+ .then(response => response.json())
49
+ .then(data => {
50
+ const geoJsonLayer = L.geoJSON(data);
51
+ geoJsonLayer.addTo(map);
52
+
53
+ // Fit map to GeoJSON bounds
54
+ map.fitBounds(geoJsonLayer.getBounds());
55
+
56
+ // Call functions from gestats.js
57
+ const areaStats = calculateTotalArea(data);
58
+ const centroid = calculateCentroid(data);
59
+ const geometryCounts = countGeometryTypes(data);
60
+ const featureNames = getFeatureNames(data);
61
+
62
+ // Display area, centroid, and geometry summary in HTML
63
+ document.getElementById('area_sqm').textContent = areaStats.areaSqMeters.toFixed(2);
64
+ document.getElementById('area_hectares').textContent = areaStats.areaHectares.toFixed(2);
65
+ document.getElementById('centroid').textContent =
66
+ `Lat: ${centroid.geometry.coordinates[1].toFixed(5)},
67
+ Lng: ${centroid.geometry.coordinates[0].toFixed(5)}`;
68
+ document.getElementById('summary').innerHTML = `
69
+ <strong>Polygons:</strong> ${geometryCounts.Polygon} <br>
70
+ <strong>Points:</strong> ${geometryCounts.Point} <br>
71
+ <strong>LineStrings:</strong> ${geometryCounts.LineString} <br>
72
+ <strong>MultiPolygons:</strong> ${geometryCounts.MultiPolygon} <br>
73
+ <strong>Feature Names:</strong> ${featureNames.length > 0 ? featureNames.join(', ') : 'N/A'}
74
+ `;
75
+ })
76
+ .catch(error => {
77
+ console.error('Error loading GeoJSON:', error);
78
+ alert('Failed to load GeoJSON file. Please check the URL.');
79
+ });
80
+ }
81
+
82
+ // Get the GeoJSON URL from the query parameter 'geojson_url'
83
+ const urlParams = new URLSearchParams(window.location.search);
84
+ const geojsonUrl = urlParams.get('geojson_url');
85
+
86
+ // Load GeoJSON if a URL is provided
87
+ if (geojsonUrl) {
88
+ loadGeoJSON(geojsonUrl);
89
+ } else {
90
+ alert('Please provide a valid GeoJSON URL in the "geojson_url" query parameter.');
91
+ }
92
+ </script>
93
+ </body>
94
+ </html>
geostats.js ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ // Function to calculate total area in square meters for polygons and multipolygons
2
+ function calculateTotalArea(data) {
3
+ let totalAreaSqMeters = 0;
4
+
5
+ data.features.forEach(feature => {
6
+ if (feature.geometry.type === "Polygon" || feature.geometry.type === "MultiPolygon") {
7
+ totalAreaSqMeters += turf.area(feature);
8
+ }
9
+ });
10
+
11
+ return {
12
+ areaSqMeters: totalAreaSqMeters,
13
+ areaHectares: totalAreaSqMeters / 10000 // Convert to hectares
14
+ };
15
+ }
16
+
17
+ // Function to calculate the centroid of all polygons and multipolygons
18
+ function calculateCentroid(data) {
19
+ const polygonsOnly = {
20
+ type: "FeatureCollection",
21
+ features: data.features.filter(f => f.geometry.type === "Polygon" || f.geometry.type === "MultiPolygon")
22
+ };
23
+
24
+ return turf.centroid(polygonsOnly);
25
+ }
26
+
27
+ // Function to count different geometry types
28
+ function countGeometryTypes(data) {
29
+ const geometryCounts = { Polygon: 0, Point: 0, LineString: 0, MultiPolygon: 0 };
30
+
31
+ data.features.forEach(feature => {
32
+ const geomType = feature.geometry.type;
33
+ if (geometryCounts[geomType] !== undefined) {
34
+ geometryCounts[geomType]++;
35
+ }
36
+ });
37
+
38
+ return geometryCounts;
39
+ }
40
+
41
+ // Function to retrieve feature names if available
42
+ function getFeatureNames(data) {
43
+ const featureNames = [];
44
+
45
+ data.features.forEach(feature => {
46
+ if (feature.properties && feature.properties.name) {
47
+ featureNames.push(feature.properties.name);
48
+ }
49
+ });
50
+
51
+ return featureNames;
52
+ }
kml.html ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dynamic KML Map</title>
5
+ <link rel="stylesheet" href="https://unpkg.com/[email protected]/dist/leaflet.css" />
6
+ <script src="https://unpkg.com/[email protected]/dist/leaflet.js"></script>
7
+ <script src="./L.KML.js"></script> <!-- Make sure this file is in the repo -->
8
+ </head>
9
+ <body>
10
+ <div style="width: 100vw; height: 100vh" id="map"></div>
11
+ <script type="text/javascript">
12
+ // Helper function to get URL parameters
13
+ function getParameterByName(name, url = window.location.href) {
14
+ name = name.replace(/[\[\]]/g, '\\$&');
15
+ const regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$)');
16
+ const results = regex.exec(url);
17
+ if (!results) return null;
18
+ if (!results[2]) return '';
19
+ return decodeURIComponent(results[2].replace(/\+/g, ' '));
20
+ }
21
+
22
+ // Get the KML URL from the URL parameter
23
+ const kmlUrl = getParameterByName('kml_url');
24
+
25
+ if (kmlUrl) {
26
+ // Initialize map
27
+ const map = new L.Map('map', { center: new L.LatLng(58.4, 43.0), zoom: 11 });
28
+ //const osm = new L.TileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png');
29
+ //const osm = new L.TileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}');
30
+ const osm = new L.TileLayer('http://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}');
31
+ map.addLayer(osm);
32
+
33
+ // Load the KML file from the given URL
34
+ fetch(kmlUrl)
35
+ .then(res => res.text())
36
+ .then(kmltext => {
37
+ const parser = new DOMParser();
38
+ const kml = parser.parseFromString(kmltext, 'text/xml');
39
+ const track = new L.KML(kml);
40
+ map.addLayer(track);
41
+
42
+ // Adjust map to show the KML
43
+ const bounds = track.getBounds();
44
+ map.fitBounds(bounds);
45
+ })
46
+ .catch(error => {
47
+ console.error('Error loading KML:', error);
48
+ alert('Failed to load KML file. Please check the URL.');
49
+ });
50
+ } else {
51
+ alert('No KML URL provided. Please use the "kml_url" parameter in the URL.');
52
+ }
53
+ </script>
54
+ </body>
55
+ </html>
streamlit-app.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import folium
3
+ from streamlit_folium import st_folium
4
+ import gdown
5
+ import os
6
+ import json
7
+ import requests
8
+
9
+ # Function to download from Google Drive
10
+ def download_from_gdrive(gdrive_url, output_path="temp_file"):
11
+ # Extract the file ID from the URL
12
+ file_id = gdrive_url.split('/d/')[1].split('/')[0]
13
+ gdrive_download_url = f"https://drive.google.com/uc?id={file_id}"
14
+ gdown.download(gdrive_download_url, output_path, quiet=False)
15
+ return output_path
16
+
17
+ # Title
18
+ st.title("KML/GeoJSON Viewer with Satellite Basemap")
19
+
20
+ # Get URL from Streamlit's query parameters
21
+ query_params = st.experimental_get_query_params()
22
+ file_url = query_params.get("file_url", [None])[0]
23
+
24
+ if file_url:
25
+ # Check if it's a Google Drive link
26
+ if "drive.google.com" in file_url:
27
+ # Download the file locally
28
+ local_file_path = download_from_gdrive(file_url)
29
+ file_extension = local_file_path.split('.')[-1]
30
+ else:
31
+ # Standard HTTP URL for direct access
32
+ try:
33
+ response = requests.get(file_url)
34
+ response.raise_for_status() # Ensure URL is valid
35
+ file_extension = file_url.split('.')[-1]
36
+
37
+ # Save the content to a local file
38
+ with open("temp_file." + file_extension, 'wb') as file:
39
+ file.write(response.content)
40
+ local_file_path = "temp_file." + file_extension
41
+ except requests.exceptions.RequestException as e:
42
+ st.error(f"Error loading file: {e}")
43
+ local_file_path = None
44
+
45
+ if local_file_path:
46
+ # Create map without default tiles
47
+ m = folium.Map(tiles=None)
48
+
49
+ # Add Google Maps basemap
50
+ folium.TileLayer(
51
+ tiles='https://mt1.google.com/vt/lyrs=r&x={x}&y={y}&z={z}',
52
+ attr='Google Maps',
53
+ name='Google Maps',
54
+ overlay=True,
55
+ control=True
56
+ ).add_to(m)
57
+
58
+ # Add Google Satellite basemap
59
+ folium.TileLayer(
60
+ tiles='https://mt1.google.com/vt/lyrs=s&x={x}&y={y}&z={z}',
61
+ attr='Google Satellite',
62
+ name='Google Satellite',
63
+ overlay=True,
64
+ control=True
65
+ ).add_to(m)
66
+
67
+ # Determine if file is KML or GeoJSON and add accordingly
68
+ if file_extension.lower() == 'kml':
69
+ folium.Kml(local_file_path).add_to(m)
70
+ elif file_extension.lower() == 'geojson':
71
+ with open(local_file_path, 'r') as file:
72
+ geojson_data = json.load(file)
73
+ folium.GeoJson(geojson_data, name="GeoJSON Data").add_to(m)
74
+ else:
75
+ st.error("Unsupported file format. Please provide a KML or GeoJSON file.")
76
+ local_file_path = None
77
+
78
+ # Center and zoom on the layer
79
+ if local_file_path:
80
+ bounds = m.get_bounds() # Adjusting the view to include KML or GeoJSON bounds
81
+ m.fit_bounds(bounds)
82
+
83
+ # Add a layer control to switch between basemaps
84
+ folium.LayerControl().add_to(m)
85
+
86
+ # Display the map in Streamlit
87
+ st_folium(m, width=700, height=500)
88
+
89
+ # Clean up the downloaded file after use
90
+ os.remove(local_file_path)
91
+
92
+ else:
93
+ st.warning("Please provide a KML or GeoJSON URL as a query parameter, e.g., `?file_url=<your_file_url>`")
style.css ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* Custom styling for GeoJSON viewer */
2
+ body, html {
3
+ margin: 0;
4
+ padding: 0;
5
+ width: 100vw;
6
+ height: 100vh;
7
+ font-family: 'Arial', sans-serif;
8
+ background-color: #e8eef1;
9
+ display: flex;
10
+ flex-direction: column;
11
+ align-items: center;
12
+ }
13
+
14
+ header {
15
+ width: 100%;
16
+ padding: 20px;
17
+ text-align: center;
18
+ background-color: #008080;
19
+ color: #fff;
20
+ font-size: 1.8em;
21
+ font-weight: bold;
22
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.2);
23
+ }
24
+
25
+ #map {
26
+ width: 95%;
27
+ height: 70vh;
28
+ margin-top: 10px;
29
+ box-shadow: 0px 4px 8px rgba(0, 0, 0, 0.1);
30
+ border-radius: 8px;
31
+ }
32
+
33
+ #stats {
34
+ width: 95%;
35
+ max-width: 800px;
36
+ margin: 20px auto;
37
+ padding: 20px;
38
+ background-color: #fff;
39
+ border-radius: 8px;
40
+ box-shadow: 0px 4px 12px rgba(0, 0, 0, 0.15);
41
+ }
42
+
43
+ #stats h3 {
44
+ font-size: 1.6em;
45
+ color: #333;
46
+ text-align: center;
47
+ margin-bottom: 10px;
48
+ }
49
+
50
+ #stats .stat-item {
51
+ display: flex;
52
+ justify-content: space-between;
53
+ align-items: center;
54
+ padding: 8px 0;
55
+ border-bottom: 1px solid #ddd;
56
+ }
57
+
58
+ #stats .stat-item:last-child {
59
+ border-bottom: none;
60
+ }
61
+
62
+ #stats .stat-label {
63
+ display: flex;
64
+ align-items: center;
65
+ font-weight: bold;
66
+ color: #555;
67
+ }
68
+
69
+ #stats .stat-label i {
70
+ font-style: normal;
71
+ color: #008080;
72
+ margin-right: 8px;
73
+ }
74
+
75
+ .value {
76
+ color: #008080;
77
+ font-weight: bold;
78
+ font-size: 1.1em;
79
+ }
80
+
81
+ footer {
82
+ padding: 10px;
83
+ text-align: center;
84
+ color: #666;
85
+ font-size: 0.9em;
86
+ }