mapdata 2.13.0__tar.gz → 2.14.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mapdata-2.13.0/mapdata.egg-info → mapdata-2.14.0}/PKG-INFO +1 -1
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata/mapdata.py +157 -27
- {mapdata-2.13.0 → mapdata-2.14.0/mapdata.egg-info}/PKG-INFO +1 -1
- {mapdata-2.13.0 → mapdata-2.14.0}/setup.py +1 -1
- {mapdata-2.13.0 → mapdata-2.14.0}/LICENSE.txt +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/MANIFEST.in +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/README.md +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata/mapdata_2.py +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata/mapdata_cli.py +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata.egg-info/SOURCES.txt +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata.egg-info/dependency_links.txt +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/mapdata.egg-info/top_level.txt +0 -0
- {mapdata-2.13.0 → mapdata-2.14.0}/setup.cfg +0 -0
|
@@ -24,8 +24,8 @@
|
|
|
24
24
|
#
|
|
25
25
|
# ==================================================================
|
|
26
26
|
|
|
27
|
-
version = "2.
|
|
28
|
-
vdate = "2023-12-
|
|
27
|
+
version = "2.14.0"
|
|
28
|
+
vdate = "2023-12-31"
|
|
29
29
|
|
|
30
30
|
copyright = "2023"
|
|
31
31
|
|
|
@@ -459,20 +459,21 @@ class CsvFile(object):
|
|
|
459
459
|
return self
|
|
460
460
|
|
|
461
461
|
|
|
462
|
-
def sort_columns(columns):
|
|
463
|
-
# Sorts a list of one, two, or three sublists, where each sublist is a column.
|
|
462
|
+
def sort_columns(columns, sortby=0):
|
|
463
|
+
# Sorts a list of one, two, or three sublists, where each sublist is a column.
|
|
464
|
+
# Rows are sorted by the 'sortby' column, which is zero-based.
|
|
464
465
|
# The returned value is also column-wise, but sorted by rows.
|
|
465
466
|
if len(columns) == 1:
|
|
466
467
|
return sorted(columns)
|
|
467
468
|
nrows = len(columns[0])
|
|
468
469
|
if len(columns) == 2:
|
|
469
470
|
rowdata = [[columns[0][i], columns[1][i]] for i in range(nrows)]
|
|
470
|
-
rowdata.sort()
|
|
471
|
+
rowdata.sort(key = lambda c: c[sortby])
|
|
471
472
|
return [[rowdata[i][0] for i in range(nrows)], [rowdata[i][1] for i in range(nrows)]]
|
|
472
473
|
else:
|
|
473
474
|
# len(columns) should be 3, though this is not checked
|
|
474
475
|
rowdata = [[columns[0][i], columns[1][i], columns[2][i]] for i in range(nrows)]
|
|
475
|
-
rowdata.sort()
|
|
476
|
+
rowdata.sort(key = lambda c: c[sortby])
|
|
476
477
|
return [[rowdata[i][0] for i in range(nrows)], [rowdata[i][1] for i in range(nrows)], [rowdata[i][2] for i in range(nrows)]]
|
|
477
478
|
|
|
478
479
|
|
|
@@ -913,6 +914,7 @@ class MapUI(object):
|
|
|
913
914
|
self.basemap_var = tk.StringVar(self.win, bm_name)
|
|
914
915
|
self.map_option_menu = ttk.Combobox(ctrlframe, state="readonly", textvariable=self.basemap_var,
|
|
915
916
|
values=self.available_tile_servers(), width=18)
|
|
917
|
+
self.map_option_menu["state"] = "normal"
|
|
916
918
|
self.map_option_menu.bind('<<ComboboxSelected>>', self.change_basemap)
|
|
917
919
|
self.map_option_menu.grid(row=0, column=1, padx=(5, 30), pady=(2, 5), sticky=tk.W)
|
|
918
920
|
# Multi-select option
|
|
@@ -1416,8 +1418,9 @@ class MapUI(object):
|
|
|
1416
1418
|
# Plotting support. Return all data for the specified columns as a list of column-oriented lists.
|
|
1417
1419
|
res = []
|
|
1418
1420
|
for c in column_list:
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
+
if c in self.headers:
|
|
1422
|
+
i = self.headers.index(c)
|
|
1423
|
+
res.append([row[i] for row in self.rows])
|
|
1421
1424
|
return res
|
|
1422
1425
|
def get_sel_data(self, column_list):
|
|
1423
1426
|
# Plotting support. Return data from selected rows for the specified columns, as a list of lists.
|
|
@@ -1469,6 +1472,9 @@ class MapUI(object):
|
|
|
1469
1472
|
clone.dlg.bind("<Alt-y>", clone.set_ylabel)
|
|
1470
1473
|
if clone.type_var.get() == "Histogram":
|
|
1471
1474
|
clone.dlg.bind("<Alt-b>", clone.set_bins)
|
|
1475
|
+
clone.alpha = plot_obj.alpha
|
|
1476
|
+
if clone.type_var.get() in ("Scatter plot", "Categorical stripchart", "Categorical KD plot"):
|
|
1477
|
+
clone.dlg.bind("<Alt-a>", clone.set_alpha)
|
|
1472
1478
|
clone.dataset = copy.copy(plot_obj.dataset)
|
|
1473
1479
|
clone.plot_data = copy.copy(plot_obj.plot_data)
|
|
1474
1480
|
clone.data_labels = copy.copy(plot_obj.data_labels)
|
|
@@ -2795,10 +2801,16 @@ class PlotDialog(object):
|
|
|
2795
2801
|
self.dlg.columnconfigure(0, weight=1)
|
|
2796
2802
|
self.auto_update = True
|
|
2797
2803
|
self.plot_title = None
|
|
2804
|
+
# For transparency on some plots
|
|
2805
|
+
self.alpha = 0.45
|
|
2798
2806
|
# For histogram
|
|
2799
2807
|
self.bins = 10
|
|
2800
2808
|
# For display of groups at Jenks breaks on Q-Q plots
|
|
2801
2809
|
self.qq_groups = False
|
|
2810
|
+
# For display of lines at X and Y Jenks breaks on scatter plots
|
|
2811
|
+
self.scatter_breaks = False
|
|
2812
|
+
self.scatter_x_breaks = None
|
|
2813
|
+
self.scatter_y_breaks = None
|
|
2802
2814
|
|
|
2803
2815
|
def set_autoupdate():
|
|
2804
2816
|
if self.autoupdate_var.get() == "1":
|
|
@@ -2930,7 +2942,7 @@ class PlotDialog(object):
|
|
|
2930
2942
|
for j in range(variables):
|
|
2931
2943
|
row.append(self.dataset[j][i])
|
|
2932
2944
|
rowwise_data.append(row)
|
|
2933
|
-
tframe, tdata = treeview_table(dlg.content_frame, rowwise_data, self.data_labels)
|
|
2945
|
+
tframe, tdata = treeview_table(dlg.content_frame, rowwise_data, self.data_labels[0:variables])
|
|
2934
2946
|
tframe.grid(row=0, column=0, sticky=tk.NSEW)
|
|
2935
2947
|
dlg.show()
|
|
2936
2948
|
|
|
@@ -2981,6 +2993,7 @@ class PlotDialog(object):
|
|
|
2981
2993
|
# Also sets the groupby Combobox values if applicable.
|
|
2982
2994
|
self.plotfig.clear()
|
|
2983
2995
|
self.plot_title = None
|
|
2996
|
+
self.dlg.bind("<Alt-a>")
|
|
2984
2997
|
self.dlg.bind("<Alt-b>")
|
|
2985
2998
|
self.dlg.bind("<Alt-g>")
|
|
2986
2999
|
self.plot_axes = self.plotfig.add_subplot(111)
|
|
@@ -2999,8 +3012,8 @@ class PlotDialog(object):
|
|
|
2999
3012
|
# quant_columns includes date and timestamp columns
|
|
3000
3013
|
quant_columns = [c[0] for c in self.column_specs if c[1] in ("int", "float", "date", "timestamp", "timestamptz")]
|
|
3001
3014
|
quant_columns.sort()
|
|
3002
|
-
numeric_columns = [c[0] for c in self.column_specs if c[1] in ("int", "float")]
|
|
3003
|
-
numeric_columns.sort()
|
|
3015
|
+
self.numeric_columns = [c[0] for c in self.column_specs if c[1] in ("int", "float")]
|
|
3016
|
+
self.numeric_columns.sort()
|
|
3004
3017
|
date_columns = [c[0] for c in self.column_specs if c[1] in ("date", "timestamp", "timestamptz")]
|
|
3005
3018
|
date_columns.sort()
|
|
3006
3019
|
self.x_var.set('')
|
|
@@ -3020,7 +3033,7 @@ class PlotDialog(object):
|
|
|
3020
3033
|
self.ylog_ck["state"] = "disabled"
|
|
3021
3034
|
elif plot_type in ("Histogram", "Empirical CDF", "Kernel density (KD) plot", "Normal Q-Q plot", "Breaks groups", "Breaks optimum"):
|
|
3022
3035
|
self.x_sel["state"] = "normal"
|
|
3023
|
-
self.x_sel["values"] = numeric_columns
|
|
3036
|
+
self.x_sel["values"] = self.numeric_columns
|
|
3024
3037
|
self.y_sel["state"] = "disabled"
|
|
3025
3038
|
self.ylog_ck["state"] = "disabled"
|
|
3026
3039
|
if plot_type == "Histogram":
|
|
@@ -3033,7 +3046,8 @@ class PlotDialog(object):
|
|
|
3033
3046
|
self.x_sel["state"] = "normal"
|
|
3034
3047
|
self.x_sel["values"] = xcols
|
|
3035
3048
|
self.xlog_ck["state"] = "disabled"
|
|
3036
|
-
self.y_sel["
|
|
3049
|
+
self.y_sel["state"] = "normal"
|
|
3050
|
+
self.y_sel["values"] = self.numeric_columns
|
|
3037
3051
|
elif plot_type == "Min-max plot":
|
|
3038
3052
|
self.x_sel["state"] = "normal"
|
|
3039
3053
|
self.x_sel["values"] = quant_columns
|
|
@@ -3047,7 +3061,7 @@ class PlotDialog(object):
|
|
|
3047
3061
|
self.y_sel["values"] = quant_columns
|
|
3048
3062
|
if plot_type in ("Scatter plot", "Line plot"):
|
|
3049
3063
|
self.groupby_sel["state"] = "normal"
|
|
3050
|
-
self.groupby_sel["values"] = [''] + categ_columns2
|
|
3064
|
+
self.groupby_sel["values"] = [''] + categ_columns2 + ['* Breaks in X', '* Breaks in Y']
|
|
3051
3065
|
|
|
3052
3066
|
def q_redraw(self, get_data=True, *args):
|
|
3053
3067
|
# Conditionally (re)draw the plot.
|
|
@@ -3117,8 +3131,9 @@ class PlotDialog(object):
|
|
|
3117
3131
|
# Set data labels
|
|
3118
3132
|
if self.y_var.get() != '':
|
|
3119
3133
|
self.data_labels = [self.x_var.get(), self.y_var.get()]
|
|
3120
|
-
|
|
3121
|
-
|
|
3134
|
+
grpvar = self.groupby_var.get()
|
|
3135
|
+
if grpvar not in ('', '* Breaks in X', '* Breaks in Y') :
|
|
3136
|
+
self.data_labels.append(grpvar)
|
|
3122
3137
|
else:
|
|
3123
3138
|
self.data_labels = [self.x_var.get()]
|
|
3124
3139
|
# Log-transform data if specified.
|
|
@@ -3246,18 +3261,49 @@ class PlotDialog(object):
|
|
|
3246
3261
|
self.plot_data_labels = [self.data_labels[0], self.data_labels[1] + " min", self.data_labels[1] + " max"]
|
|
3247
3262
|
elif plot_type == "Line plot":
|
|
3248
3263
|
# Sort by X
|
|
3249
|
-
if self.groupby_var.get() == '':
|
|
3250
|
-
|
|
3251
|
-
else:
|
|
3252
|
-
|
|
3253
|
-
ds.sort()
|
|
3254
|
-
ds2 = list(zip(*ds))
|
|
3264
|
+
#if self.groupby_var.get() == '':
|
|
3265
|
+
# ds = list(zip(self.dataset[0], self.dataset[1]))
|
|
3266
|
+
#else:
|
|
3267
|
+
# ds = list(zip(self.dataset[0], self.dataset[1], self.dataset[2]))
|
|
3268
|
+
#ds.sort()
|
|
3269
|
+
#ds2 = list(zip(*ds))
|
|
3270
|
+
ds2 = sort_columns(self.dataset)
|
|
3255
3271
|
if self.groupby_var.get() == '':
|
|
3256
3272
|
self.plot_data = [list(ds2[0]), list(ds2[1])]
|
|
3257
3273
|
else:
|
|
3258
3274
|
self.plot_data = [list(ds2[0]), list(ds2[1]), list(ds2[2])]
|
|
3259
3275
|
self.plot_data_labels = self.data_labels
|
|
3260
|
-
elif plot_type
|
|
3276
|
+
elif plot_type == "Scatter plot":
|
|
3277
|
+
if self.groupby_var.get() == "* Breaks in X":
|
|
3278
|
+
if self.x_var.get() in self.numeric_columns:
|
|
3279
|
+
ds = sort_columns(self.dataset)
|
|
3280
|
+
oj = optimum_jenks(ds[0], 8)
|
|
3281
|
+
jnb = jenkspy.JenksNaturalBreaks(oj)
|
|
3282
|
+
jnb.fit(ds[0])
|
|
3283
|
+
self.plot_data = [ds[0], ds[1], ["Group "+str(lbl+1) for lbl in jnb.labels_]]
|
|
3284
|
+
self.plot_data_labels = self.data_labels + ['Breaks in X']
|
|
3285
|
+
else:
|
|
3286
|
+
# Can't compute breaks for X
|
|
3287
|
+
self.groupby_var.set('')
|
|
3288
|
+
self.plot_data = self.dataset
|
|
3289
|
+
self.plot_data_labels = self.data_labels
|
|
3290
|
+
elif self.groupby_var.get() == "* Breaks in Y":
|
|
3291
|
+
if self.y_var.get() in self.numeric_columns:
|
|
3292
|
+
ds = sort_columns(self.dataset, sortby=1)
|
|
3293
|
+
oj = optimum_jenks(ds[1], 8)
|
|
3294
|
+
jnb = jenkspy.JenksNaturalBreaks(oj)
|
|
3295
|
+
jnb.fit(ds[1])
|
|
3296
|
+
self.plot_data = [ds[0], ds[1], ["Group "+str(lbl+1) for lbl in jnb.labels_]]
|
|
3297
|
+
self.plot_data_labels = self.data_labels + ['Breaks in Y']
|
|
3298
|
+
else:
|
|
3299
|
+
# Can't compute breaks for Y
|
|
3300
|
+
self.groupby_var.set('')
|
|
3301
|
+
self.plot_data = self.dataset
|
|
3302
|
+
self.plot_data_labels = self.data_labels
|
|
3303
|
+
else:
|
|
3304
|
+
self.plot_data = self.dataset
|
|
3305
|
+
self.plot_data_labels = self.data_labels
|
|
3306
|
+
elif plot_type in ("Histogram", "Y range plot"):
|
|
3261
3307
|
# No special preparation
|
|
3262
3308
|
self.plot_data = self.dataset
|
|
3263
3309
|
self.plot_data_labels = self.data_labels
|
|
@@ -3275,8 +3321,29 @@ class PlotDialog(object):
|
|
|
3275
3321
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3276
3322
|
self.plot_axes.set_ylabel("Counts")
|
|
3277
3323
|
elif plot_type == "Scatter plot":
|
|
3324
|
+
self.dlg.bind("<Alt-a>", self.set_alpha)
|
|
3325
|
+
self.dlg.bind("<Alt-b>", self.set_scatter_breaks)
|
|
3326
|
+
if self.scatter_breaks:
|
|
3327
|
+
if self.x_var.get() in self.numeric_columns:
|
|
3328
|
+
x_vals = copy.copy(self.plot_data[0])
|
|
3329
|
+
x_vals.sort()
|
|
3330
|
+
oj = optimum_jenks(x_vals, 8)
|
|
3331
|
+
jnb = jenkspy.JenksNaturalBreaks(oj)
|
|
3332
|
+
jnb.fit(x_vals)
|
|
3333
|
+
self.scatter_x_breaks = jnb.inner_breaks_
|
|
3334
|
+
for b in self.scatter_x_breaks:
|
|
3335
|
+
self.plot_axes.axvline(b, color='0.8', alpha=0.5)
|
|
3336
|
+
if self.y_var.get() in self.numeric_columns:
|
|
3337
|
+
y_vals = copy.copy(self.plot_data[1])
|
|
3338
|
+
y_vals.sort()
|
|
3339
|
+
oj = optimum_jenks(y_vals, 8)
|
|
3340
|
+
jnb = jenkspy.JenksNaturalBreaks(oj)
|
|
3341
|
+
jnb.fit(y_vals)
|
|
3342
|
+
self.scatter_y_breaks = jnb.inner_breaks_
|
|
3343
|
+
for b in self.scatter_y_breaks:
|
|
3344
|
+
self.plot_axes.axhline(b, color='0.8', alpha=0.5)
|
|
3278
3345
|
if self.groupby_var.get() == '':
|
|
3279
|
-
self.plot_axes.scatter(self.plot_data[0], self.plot_data[1])
|
|
3346
|
+
self.plot_axes.scatter(self.plot_data[0], self.plot_data[1], alpha=self.alpha)
|
|
3280
3347
|
else:
|
|
3281
3348
|
groups = list(set(self.plot_data[2]))
|
|
3282
3349
|
groups.sort()
|
|
@@ -3284,7 +3351,7 @@ class PlotDialog(object):
|
|
|
3284
3351
|
for g in groups:
|
|
3285
3352
|
pdx = [self.plot_data[0][i] for i in range(datarows) if self.plot_data[2][i] == g]
|
|
3286
3353
|
pdy = [self.plot_data[1][i] for i in range(datarows) if self.plot_data[2][i] == g]
|
|
3287
|
-
self.plot_axes.plot(pdx, pdy, marker='o', linestyle='', label=g)
|
|
3354
|
+
self.plot_axes.plot(pdx, pdy, marker='o', alpha=self.alpha, linestyle='', label=g)
|
|
3288
3355
|
self.plot_axes.legend()
|
|
3289
3356
|
self.plot_axes.set_xlabel(self.plot_data_labels[0])
|
|
3290
3357
|
self.plot_axes.set_ylabel(self.plot_data_labels[1])
|
|
@@ -3362,14 +3429,16 @@ class PlotDialog(object):
|
|
|
3362
3429
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3363
3430
|
self.plot_axes.set_ylabel(self.data_labels[1])
|
|
3364
3431
|
elif plot_type == "Categorical KD plot":
|
|
3432
|
+
self.dlg.bind("<Alt-a>", self.set_alpha)
|
|
3365
3433
|
sns.kdeplot({self.x_var.get(): self.dataset[0], self.y_var.get(): self.dataset[1]},
|
|
3366
|
-
x=self.y_var.get(), hue=self.x_var.get(), multiple="layer", fill=True, alpha=
|
|
3434
|
+
x=self.y_var.get(), hue=self.x_var.get(), multiple="layer", fill=True, alpha=self.alpha, ax=self.plot_axes,
|
|
3367
3435
|
warn_singular=False)
|
|
3368
3436
|
self.plot_axes.set_xlabel(self.y_var.get())
|
|
3369
3437
|
self.plot_axes.set_ylabel("Density")
|
|
3370
3438
|
elif plot_type == "Categorical stripchart":
|
|
3439
|
+
self.dlg.bind("<Alt-a>", self.set_alpha)
|
|
3371
3440
|
sns.stripplot({self.x_var.get(): self.dataset[0], self.y_var.get(): self.dataset[1]},
|
|
3372
|
-
x=self.x_var.get(), y=self.y_var.get(), alpha=
|
|
3441
|
+
x=self.x_var.get(), y=self.y_var.get(), alpha=self.alpha, ax=self.plot_axes)
|
|
3373
3442
|
self.plot_axes.set_xlabel(self.x_var.get())
|
|
3374
3443
|
self.plot_axes.set_ylabel(self.data_labels[1])
|
|
3375
3444
|
elif plot_type == "Violin plot":
|
|
@@ -3408,6 +3477,20 @@ class PlotDialog(object):
|
|
|
3408
3477
|
self.bins = num_bins
|
|
3409
3478
|
if self.type_var.get() == "Histogram":
|
|
3410
3479
|
self.q_redraw()
|
|
3480
|
+
def set_alpha(self, *args):
|
|
3481
|
+
dlg = OneFloatDialog(self.dlg, "Transparency", "Enter the transparency (alpha) value", min_value=0.0, max_value=1.0, initial=self.alpha)
|
|
3482
|
+
new_alpha = dlg.show()
|
|
3483
|
+
if new_alpha is not None:
|
|
3484
|
+
self.alpha = new_alpha
|
|
3485
|
+
if self.type_var.get() in ("Scatter plot", "Categorical stripchart", "Categorical KD plot"):
|
|
3486
|
+
self.q_redraw()
|
|
3487
|
+
def set_scatter_breaks(self, *args):
|
|
3488
|
+
# Toggle display of vertical and horizontal lines at natural breaks values on a scatter plot.
|
|
3489
|
+
# plot_data[0] and plot_data[1] must be x and y, respectively.
|
|
3490
|
+
self.scatter_breaks = not self.scatter_breaks
|
|
3491
|
+
if self.type_var.get() == "Scatter plot":
|
|
3492
|
+
self.q_redraw()
|
|
3493
|
+
|
|
3411
3494
|
def show_groups(self, *args):
|
|
3412
3495
|
if self.type_var.get() == "Normal Q-Q plot":
|
|
3413
3496
|
self.qq_groups = not self.qq_groups
|
|
@@ -3625,6 +3708,53 @@ class OneIntDialog(object):
|
|
|
3625
3708
|
return self.entry_var.get()
|
|
3626
3709
|
|
|
3627
3710
|
|
|
3711
|
+
class OneFloatDialog(object):
|
|
3712
|
+
def __init__(self, parent, title, prompt, min_value, max_value, initial):
|
|
3713
|
+
self.dlg = tk.Toplevel(parent)
|
|
3714
|
+
self.dlg.title(title)
|
|
3715
|
+
prompt_frame = tk.Frame(self.dlg)
|
|
3716
|
+
prompt_frame.grid(row=0, column=0, sticky=tk.NSEW, pady=(3,3))
|
|
3717
|
+
prompt_frame.columnconfigure(0, weight=1)
|
|
3718
|
+
msg_lbl = ttk.Label(prompt_frame, text=prompt)
|
|
3719
|
+
msg_lbl.grid(row=0, column=0, sticky=tk.W, padx=(6,6), pady=(6,6))
|
|
3720
|
+
self.entry_var = tk.DoubleVar(self.dlg, initial)
|
|
3721
|
+
self.val_entry = ttk.Spinbox(prompt_frame, textvariable=self.entry_var, from_=min_value, to=max_value)
|
|
3722
|
+
self.val_entry.grid(row=1, column=0, sticky=tk.EW, padx=(6,6), pady=(3,3))
|
|
3723
|
+
btn_frame = tk.Frame(self.dlg, borderwidth=3, relief=tk.RIDGE)
|
|
3724
|
+
btn_frame.columnconfigure(0, weight=1)
|
|
3725
|
+
btn_frame.grid(row=2, column=0, sticky=tk.EW, pady=(3,3))
|
|
3726
|
+
btn_frame.columnconfigure(0, weight=1)
|
|
3727
|
+
self.val_entry.focus()
|
|
3728
|
+
# Buttons
|
|
3729
|
+
self.canceled = False
|
|
3730
|
+
self.ok_btn = ttk.Button(btn_frame, text="OK", command=self.do_select, underline=0)
|
|
3731
|
+
self.ok_btn.grid(row=0, column=0, sticky=tk.E, padx=(6,3))
|
|
3732
|
+
self.dlg.bind('<Alt-o>', self.do_select)
|
|
3733
|
+
cancel_btn = ttk.Button(btn_frame, text="Cancel", command=self.do_cancel, underline=0)
|
|
3734
|
+
cancel_btn.grid(row=0, column=1, sticky=tk.E, padx=(3,6))
|
|
3735
|
+
self.dlg.bind("<Escape>", self.do_cancel)
|
|
3736
|
+
self.dlg.bind("<Alt-c>", self.do_cancel)
|
|
3737
|
+
self.dlg.bind("<Return>", self.do_select)
|
|
3738
|
+
self.dlg.bind("<Alt-o>", self.do_select)
|
|
3739
|
+
def do_cancel(self, *args):
|
|
3740
|
+
self.canceled = True
|
|
3741
|
+
self.dlg.destroy()
|
|
3742
|
+
def do_select(self, *args):
|
|
3743
|
+
self.canceled = False
|
|
3744
|
+
self.dlg.destroy()
|
|
3745
|
+
def show(self):
|
|
3746
|
+
self.dlg.grab_set()
|
|
3747
|
+
center_window(self.dlg)
|
|
3748
|
+
raise_window(self.dlg)
|
|
3749
|
+
self.dlg.resizable(True, False)
|
|
3750
|
+
self.dlg.attributes('-topmost', 'true')
|
|
3751
|
+
self.dlg.wait_window(self.dlg)
|
|
3752
|
+
if self.canceled:
|
|
3753
|
+
return None
|
|
3754
|
+
else:
|
|
3755
|
+
return self.entry_var.get()
|
|
3756
|
+
|
|
3757
|
+
|
|
3628
3758
|
class GetEditorDialog(object):
|
|
3629
3759
|
def __init__(self, parent, current_editor):
|
|
3630
3760
|
self.dlg = tk.Toplevel(parent)
|
|
@@ -5,7 +5,7 @@ with io.open('README.md', encoding='utf-8') as f:
|
|
|
5
5
|
long_description = f.read()
|
|
6
6
|
|
|
7
7
|
setuptools.setup(name='mapdata',
|
|
8
|
-
version='2.
|
|
8
|
+
version='2.14.0',
|
|
9
9
|
description="An interactive map and table explorer for geographic coordinates in a spreadsheet, CSV file, or database",
|
|
10
10
|
author='Dreas Nielsen',
|
|
11
11
|
author_email='dreas.nielsen@gmail.com',
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|