diff --git a/BuildTools/windows/GeoDa.vcxproj b/BuildTools/windows/GeoDa.vcxproj
index 5ec5c80ec..254e974dc 100644
--- a/BuildTools/windows/GeoDa.vcxproj
+++ b/BuildTools/windows/GeoDa.vcxproj
@@ -389,12 +389,19 @@
+
+
+
+
+
+
+
-
+
@@ -423,6 +430,7 @@
+
@@ -538,9 +546,11 @@
-
-
-
+
+
+
+
+
@@ -548,7 +558,6 @@
-
@@ -711,6 +720,7 @@
+
diff --git a/BuildTools/windows/GeoDa.vcxproj.filters b/BuildTools/windows/GeoDa.vcxproj.filters
index eb6d733be..fe8d541fa 100644
--- a/BuildTools/windows/GeoDa.vcxproj.filters
+++ b/BuildTools/windows/GeoDa.vcxproj.filters
@@ -50,6 +50,12 @@
{85fd04ff-4aa4-45d8-8492-8a7d69f0dc17}
+
+ {5afad44a-83ce-4cf0-bb16-70dcd9e4b1e6}
+
+
+ {dcde4097-4967-4ebe-98cd-897b7657a5d2}
+
@@ -729,39 +735,6 @@
DialogTools
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
Algorithms
@@ -841,6 +814,45 @@
DialogTools
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ Weights
+
+
+ kNN\ANN
+
+
+ kNN\ANN
+
+
+ kNN\ANN
+
@@ -1419,27 +1431,6 @@
DialogTools
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
-
- kNN
-
Algorithms
@@ -1509,5 +1500,50 @@
DialogTools
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ kNN
+
+
+ Weights
+
\ No newline at end of file
diff --git a/DataViewer/OGRTable.cpp b/DataViewer/OGRTable.cpp
index cb250a042..802a4b2d3 100644
--- a/DataViewer/OGRTable.cpp
+++ b/DataViewer/OGRTable.cpp
@@ -557,6 +557,16 @@ bool OGRTable::DoesNameExist(const wxString& name, bool case_sensitive) const
return var_order.DoesNameExist(name, case_sensitive);
}
+int OGRTable::GetFirstNumericCol()
+{
+ int n = GetNumberCols(); // var_order size
+ for (size_t i=0; i ds_var_set;
- BOOST_FOREACH(const wxString &v, ds_var_list) { ds_var_set.insert(v); }
+ BOOST_FOREACH(const wxString &v, ds_var_list) { ds_var_set.insert(v.Lower()); }
set var_set;
set group_nm_set;
BOOST_FOREACH(const VarGroup& e, var_grps) {
if (e.vars.size() == 0) {
- var_set.insert(e.name);
+ var_set.insert(e.name.Lower());
} else {
group_nm_set.insert(e.name);
BOOST_FOREACH(const wxString& v, e.vars) {
- if (!v.empty()) var_set.insert(v);
+ if (!v.empty()) var_set.insert(v.Lower());
}
}
}
diff --git a/DialogTools/AbstractClusterDlg.cpp b/DialogTools/AbstractClusterDlg.cpp
index 1ad086458..beed5f250 100644
--- a/DialogTools/AbstractClusterDlg.cpp
+++ b/DialogTools/AbstractClusterDlg.cpp
@@ -739,7 +739,7 @@ double AbstractClusterDlg::CreateSummary(const vector >& solution, c
summary << _printConfiguration();
// auto weighting
- if (m_use_centroids->IsChecked()) {
+ if (m_use_centroids != NULL && m_use_centroids->IsChecked()) {
wxString w_val = m_wc_txt->GetValue();
double w_valf = 0;
if (w_val.ToDouble(&w_valf)) {
diff --git a/DialogTools/CsvFieldConfDlg.cpp b/DialogTools/CsvFieldConfDlg.cpp
index 160efd06a..f971d601b 100644
--- a/DialogTools/CsvFieldConfDlg.cpp
+++ b/DialogTools/CsvFieldConfDlg.cpp
@@ -67,7 +67,7 @@ CsvFieldConfDlg::CsvFieldConfDlg(wxWindow* parent,
{
wxLogMessage("Open CsvFieldConfDlg.");
-
+ HEADERS = 1;
lat_box = NULL;
n_max_rows = 10;
filepath = _filepath;
diff --git a/DialogTools/HDBScanDlg.cpp b/DialogTools/HDBScanDlg.cpp
index 293343b3e..98520915a 100644
--- a/DialogTools/HDBScanDlg.cpp
+++ b/DialogTools/HDBScanDlg.cpp
@@ -488,23 +488,31 @@ void HDBScanDlg::OnOKClick(wxCommandEvent& event )
*/
double** ragged_distances = distancematrix(rows, columns, input_data, mask, weight, dist, transpose);
double** distances = DataUtils::fullRaggedMatrix(ragged_distances, rows, rows);
+
for (int i = 1; i < rows; i++) free(ragged_distances[i]);
free(ragged_distances);
// add weight to input_data
+ double** data = new double*[rows];
for (int i=0; i clusters(rows, 0);
diff --git a/DialogTools/RedcapDlg.cpp b/DialogTools/RedcapDlg.cpp
index e8b506cf7..8799c11b4 100644
--- a/DialogTools/RedcapDlg.cpp
+++ b/DialogTools/RedcapDlg.cpp
@@ -387,11 +387,31 @@ void RedcapDlg::OnSaveTree(wxCommandEvent& event )
{
if (weights && redcap) {
wxString filter = "GWT|*.gwt";
- wxFileDialog dialog(NULL, _("Save Spanning Tree to a Weights File"), wxEmptyString,
+ wxFileDialog dialog(NULL, _("Save Spanning Tree to a Weights File"),
+ wxEmptyString,
wxEmptyString, filter,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
- if (dialog.ShowModal() != wxID_OK)
+ if (dialog.ShowModal() != wxID_OK) {
return;
+ }
+ // get info from input weights
+ vector weights_ids;
+ WeightsManInterface* w_man_int = project->GetWManInt();
+ w_man_int->GetIds(weights_ids);
+ int sel = combo_weights->GetSelection();
+ if (sel < 0) sel = 0;
+ if (sel >= weights_ids.size()) sel = weights_ids.size()-1;
+ boost::uuids::uuid w_id = weights_ids[sel];
+ GalWeight* gw = w_man_int->GetGal(w_id);
+ GeoDaWeight* gdw = (GeoDaWeight*)gw;
+ wxString id = gdw->GetIDName();
+ int col = table_int->FindColId(id);
+ if (col < 0) {
+ return;
+ }
+ vector ids;
+ table_int->GetColData(col, 0, ids);
+
wxFileName fname = wxFileName(dialog.GetPath());
wxString new_main_dir = fname.GetPathWithSep();
wxString new_main_name = fname.GetName();
@@ -402,20 +422,27 @@ void RedcapDlg::OnSaveTree(wxCommandEvent& event )
file.Clear();
wxString header;
- header << "0 " << project->GetNumRecords() << " " << project->GetProjectTitle();
+ header << "0 " << project->GetNumRecords() << " " << project->GetProjectTitle() << " " << id;
file.AddLine(header);
+
for (int i=0; iordered_edges.size(); i++) {
wxString line;
- line << redcap->ordered_edges[i]->orig->id+1<< " " << redcap->ordered_edges[i]->dest->id +1<< " " << redcap->ordered_edges[i]->length ;
- file.AddLine(line);
+ int from_idx = redcap->ordered_edges[i]->orig->id;
+ int to_idx = redcap->ordered_edges[i]->dest->id;
+ double cost = redcap->ordered_edges[i]->length;
+ wxString line1;
+ line1 << ids[from_idx] << " " << ids[to_idx] << " " << cost;
+ file.AddLine(line1);
+ wxString line2;
+ line2 << ids[to_idx] << " " << ids[from_idx] << " " << cost;
+ file.AddLine(line2);
}
file.Write();
file.Close();
// Load the weights file into Weights Manager
- WeightsManInterface* w_man_int = project->GetWManInt();
- WeightUtils::LoadGwtInMan(w_man_int, new_txt, table_int);
+ WeightUtils::LoadGwtInMan(w_man_int, new_txt, table_int, id);
}
}
diff --git a/DialogTools/SkaterDlg.cpp b/DialogTools/SkaterDlg.cpp
index 8bc82eae0..660cac2ad 100644
--- a/DialogTools/SkaterDlg.cpp
+++ b/DialogTools/SkaterDlg.cpp
@@ -225,12 +225,31 @@ void SkaterDlg::OnSaveTree(wxCommandEvent& event )
{
if (skater) {
wxString filter = "GWT|*.gwt";
- wxFileDialog dialog(NULL, _("Save Spanning Tree to a Weights File"), wxEmptyString,
+ wxFileDialog dialog(NULL, _("Save Spanning Tree to a Weights File"),
+ wxEmptyString,
wxEmptyString, filter,
wxFD_SAVE | wxFD_OVERWRITE_PROMPT);
if (dialog.ShowModal() != wxID_OK) {
return;
}
+ // get info from input weights
+ vector weights_ids;
+ WeightsManInterface* w_man_int = project->GetWManInt();
+ w_man_int->GetIds(weights_ids);
+ int sel = combo_weights->GetSelection();
+ if (sel < 0) sel = 0;
+ if (sel >= weights_ids.size()) sel = weights_ids.size()-1;
+ boost::uuids::uuid w_id = weights_ids[sel];
+ GalWeight* gw = w_man_int->GetGal(w_id);
+ GeoDaWeight* gdw = (GeoDaWeight*)gw;
+ wxString id = gdw->GetIDName();
+ int col = table_int->FindColId(id);
+ if (col < 0) {
+ return;
+ }
+ vector ids;
+ table_int->GetColData(col, 0, ids);
+
wxFileName fname = wxFileName(dialog.GetPath());
wxString new_main_dir = fname.GetPathWithSep();
wxString new_main_name = fname.GetName();
@@ -241,20 +260,26 @@ void SkaterDlg::OnSaveTree(wxCommandEvent& event )
file.Clear();
wxString header;
- header << "0 " << project->GetNumRecords() << " " << project->GetProjectTitle();
+ header << "0 " << project->GetNumRecords() << " " << project->GetProjectTitle() << " " << id;
file.AddLine(header);
+
for (int i=0; iordered_edges.size(); i++) {
- wxString line;
- line << skater->ordered_edges[i]->orig->id+1<< " " << skater->ordered_edges[i]->dest->id +1<< " " << skater->ordered_edges[i]->length ;
- file.AddLine(line);
+ int from_idx = skater->ordered_edges[i]->orig->id;
+ int to_idx = skater->ordered_edges[i]->dest->id;
+ double cost = skater->ordered_edges[i]->length;
+ wxString line1;
+ line1 << ids[from_idx] << " " << ids[to_idx] << " " << cost;
+ file.AddLine(line1);
+ wxString line2;
+ line2 << ids[to_idx] << " " << ids[from_idx] << " " << cost;
+ file.AddLine(line2);
}
file.Write();
file.Close();
// Load the weights file into Weights Manager
- WeightsManInterface* w_man_int = project->GetWManInt();
- WeightUtils::LoadGwtInMan(w_man_int, new_txt, table_int);
+ WeightUtils::LoadGwtInMan(w_man_int, new_txt, table_int, id);
}
}
diff --git a/DialogTools/SpectralClusteringDlg.cpp b/DialogTools/SpectralClusteringDlg.cpp
index 26a10ac79..20ddf6c8f 100644
--- a/DialogTools/SpectralClusteringDlg.cpp
+++ b/DialogTools/SpectralClusteringDlg.cpp
@@ -611,13 +611,16 @@ void SpectralClusteringDlg::OnOK(wxCommandEvent& event )
int affinity_type = 0;
// add weight to input_data
+ double** data = new double*[rows];
for (int i=0; iIsChecked()) {
@@ -629,9 +632,13 @@ void SpectralClusteringDlg::OnOK(wxCommandEvent& event )
affinity_type = 1;
}
spectral.cluster(affinity_type);
-
-
+
vector clusters = spectral.get_assignments();
+
+ for (int i=0; i clusters_undef;
diff --git a/DialogTools/VariableSettingsDlg.cpp b/DialogTools/VariableSettingsDlg.cpp
index a1d589912..b6e354f4c 100644
--- a/DialogTools/VariableSettingsDlg.cpp
+++ b/DialogTools/VariableSettingsDlg.cpp
@@ -620,7 +620,8 @@ all_init(false),
var1_str(_var1_str),
var2_str(_var2_str),
var3_str(_var3_str),
-var4_str(_var4_str)
+var4_str(_var4_str),
+style(0)
{
wxLogMessage("Open VariableSettingsDlg");
@@ -643,6 +644,61 @@ var4_str(_var4_str)
Centre();
all_init = true;
}
+
+VariableSettingsDlg::VariableSettingsDlg(Project* project_s,
+ VarType v_type_s,
+ int style_s,
+ const wxString& title_s,
+ const wxString& var1_title_s,
+ const wxString& var2_title_s,
+ const wxString& var3_title_s,
+ const wxString& var4_title_s)
+: project(project_s),
+table_int(project_s->GetTableInt()),
+no_weights_found_fail(false),
+is_time(project_s->GetTableInt()->IsTimeVariant()),
+time_steps(project_s->GetTableInt()->GetTimeSteps()),
+title(title_s),
+var1_title(var1_title_s),
+var2_title(var2_title_s),
+var3_title(var3_title_s),
+var4_title(var4_title_s),
+num_cats_spin(0),
+num_categories(4),
+hide_time(hide_time),
+all_init(false),
+style(style_s),
+show_weights(style & SHOW_WEIGHTS),
+show_distance(style & SHOW_DISTANCE),
+set_second_from_first_mode(style & SET_SECOND_FROM_FIRST),
+set_fourth_from_third_mode(style & SET_FOURTH_FROM_THIRD),
+var1_str(style & ALLOW_STRING_IN_FIRST),
+var2_str(style & ALLOW_STRING_IN_SECOND),
+var3_str(style & ALLOW_STRING_IN_THIRD),
+var4_str(style & ALLOW_STRING_IN_FOURTH)
+{
+ wxLogMessage("Open VariableSettingsDlg");
+
+ default_var_name1 = project->GetDefaultVarName(0);
+ default_var_name2 = project->GetDefaultVarName(1);
+ default_var_name3 = project->GetDefaultVarName(2);
+ default_var_name4 = project->GetDefaultVarName(3);
+
+ if (show_weights && project->GetWManInt()->GetIds().size() == 0) {
+ no_weights_found_fail = true;
+ wxXmlResource::Get()->LoadDialog(this, GetParent(),
+ "ID_VAR_SETTINGS_NO_W_FAIL_DLG");
+ SetTitle("No Weights Found");
+ } else {
+ Init(v_type_s);
+ }
+ SetParent(0);
+ GetSizer()->Fit(this);
+ GetSizer()->SetSizeHints(this);
+ Centre();
+ all_init = true;
+}
+
VariableSettingsDlg::~VariableSettingsDlg()
{
@@ -974,7 +1030,10 @@ void VariableSettingsDlg::OnVar1Change(wxCommandEvent& event)
{
if (!all_init)
return;
- lb1_cur_sel = lb1->GetSelection();
+ lb1_cur_sel = lb1->GetSelection();
+ if (style & ALLOW_EMPTY_IN_FIRST) {
+ lb1_cur_sel = lb1_cur_sel == 0 ? 0 : lb1_cur_sel - 1;
+ }
if (lb1_cur_sel >= 0) {
int x_pos = sel1_idx_map[lb1_cur_sel];
if (x_pos >= 0)
@@ -994,7 +1053,10 @@ void VariableSettingsDlg::OnVar2Change(wxCommandEvent& event)
{
if (!all_init)
return;
- lb2_cur_sel = lb2->GetSelection();
+ lb2_cur_sel = lb2->GetSelection();
+ if (style & ALLOW_EMPTY_IN_SECOND) {
+ lb2_cur_sel = lb2_cur_sel == 0 ? 0 : lb2_cur_sel - 1;
+ }
if (lb2_cur_sel >= 0) {
int x_pos = sel2_idx_map[lb2_cur_sel];
if (x_pos >= 0)
@@ -1054,6 +1116,22 @@ void VariableSettingsDlg::OnCancelClick(wxCommandEvent& event)
event.Skip();
EndDialog(wxID_CANCEL);
}
+
+bool VariableSettingsDlg::IsFirstVariableEmpty()
+{
+ if (style & ALLOW_EMPTY_IN_FIRST) {
+ return lb1->GetSelection() == 0;
+ }
+ return false;
+}
+
+bool VariableSettingsDlg::IsSecondVariableEmpty()
+{
+ if (style & ALLOW_EMPTY_IN_SECOND) {
+ return lb2->GetSelection() == 0;
+ }
+ return false;
+}
void VariableSettingsDlg::OnOkClick(wxCommandEvent& event)
{
@@ -1063,7 +1141,18 @@ void VariableSettingsDlg::OnOkClick(wxCommandEvent& event)
EndDialog(wxID_CANCEL);
return;
}
-
+
+ if ((style & ALLOW_EMPTY_IN_FIRST) &&
+ (style & ALLOW_EMPTY_IN_SECOND)) {
+ if (lb1->GetSelection() == 0 &&
+ lb2->GetSelection() == 0) {
+ wxString msg(_("No field chosen for first and second variable."));
+ wxMessageDialog dlg (this, msg, _("Error"), wxOK | wxICON_ERROR);
+ dlg.ShowModal();
+ return;
+ }
+ }
+
if (map_theme_ch) {
m_theme = map_theme_ch->GetSelection();
}
@@ -1074,8 +1163,11 @@ void VariableSettingsDlg::OnOkClick(wxCommandEvent& event)
dlg.ShowModal();
return;
}
-
- v1_col_id = col_id_map[sel1_idx_map[lb1->GetSelection()]];
+ int sel_idx = lb1->GetSelection();
+ if (style & ALLOW_EMPTY_IN_FIRST) {
+ sel_idx = sel_idx - 1;
+ }
+ v1_col_id = col_id_map[sel1_idx_map[sel_idx]];
v1_name = table_int->GetColName(v1_col_id);
project->SetDefaultVarName(0, v1_name);
@@ -1093,8 +1185,12 @@ void VariableSettingsDlg::OnOkClick(wxCommandEvent& event)
wxMessageDialog dlg (this, msg, _("Error"), wxOK | wxICON_ERROR);
dlg.ShowModal();
return;
- }
- v2_col_id = col_id_map[sel2_idx_map[lb2->GetSelection()]];
+ }
+ int sel_idx = lb2->GetSelection();
+ if (style & ALLOW_EMPTY_IN_SECOND) {
+ sel_idx = sel_idx - 1;
+ }
+ v2_col_id = col_id_map[sel2_idx_map[sel_idx]];
v2_name = table_int->GetColName(v2_col_id);
project->SetDefaultVarName(1, v2_name);
if (is_time) {
@@ -1150,9 +1246,9 @@ void VariableSettingsDlg::OnOkClick(wxCommandEvent& event)
} else {
- if (show_weights)
+ if (show_weights) {
project->GetWManInt()->MakeDefault(GetWeightsId());
-
+ }
if (GetDistanceMetric() != WeightsMetaInfo::DM_unspecified) {
project->SetDefaultDistMetric(GetDistanceMetric());
}
@@ -1316,6 +1412,14 @@ void VariableSettingsDlg::InitFieldChoices()
int sel2_idx = 0;
int sel3_idx = 0;
int sel4_idx = 0;
+
+ if (style & ALLOW_EMPTY_IN_FIRST) {
+ lb1->Append(" "); // empty selection
+ }
+
+ if (style & ALLOW_EMPTY_IN_SECOND) {
+ lb2->Append(" "); // empty selection
+ }
for (int i=0, iend=col_id_map.size(); iGetColType(col_id_map[i]);
@@ -1380,6 +1484,8 @@ void VariableSettingsDlg::InitFieldChoices()
}
}
+
+
for (int i=0, iend=col_id_map.size(); iGetColName(col_id_map[i]);
@@ -1446,11 +1552,21 @@ bool VariableSettingsDlg::CheckEmptyColumn(int col_id, int time)
wxString VariableSettingsDlg::FillData()
{
wxString emptyVar;
+
col_ids.resize(num_var);
var_info.resize(num_var);
- if (num_var >= 1) {
- int sel_idx = lb1->GetSelection();
+ if (num_var >= 1) {
+ int sel_idx = lb1->GetSelection();
+ if (style & ALLOW_EMPTY_IN_FIRST) {
+ if (sel_idx == 0) {
+ // no selection: case ConditionalMap,
+ sel_idx = table_int->GetFirstNumericCol();
+ var_info[0].is_hide = true;
+ } else {
+ sel_idx = sel_idx - 1;
+ }
+ }
int col_idx = sel1_idx_map[sel_idx];
v1_col_id = col_id_map[col_idx];
v1_name = table_int->GetColName(v1_col_id);
@@ -1461,17 +1577,25 @@ wxString VariableSettingsDlg::FillData()
emptyVar = v1_name;
}
}
- if (num_var >= 2) {
- //v2_col_id = col_id_map[lb2->GetSelection()];
- int sel_idx = lb2->GetSelection();
- int col_idx = sel2_idx_map[sel_idx];
- v2_col_id = col_id_map[col_idx];
- v2_name = table_int->GetColName(v2_col_id);
- col_ids[1] = v2_col_id;
- var_info[1].time = v2_time;
-
- if (emptyVar.empty() && CheckEmptyColumn(v2_col_id, v2_time)) {
- emptyVar = v2_name;
+ if (num_var >= 2) {
+ int sel_idx = lb2->GetSelection();
+ if (style & ALLOW_EMPTY_IN_SECOND) {
+ if (sel_idx == 0) {
+ // no selection: case ConditionalMap,
+ sel_idx = table_int->GetFirstNumericCol();
+ var_info[1].is_hide = true;
+ } else {
+ sel_idx = sel_idx - 1;
+ }
+ }
+ int col_idx = sel2_idx_map[sel_idx];
+ v2_col_id = col_id_map[col_idx];
+ v2_name = table_int->GetColName(v2_col_id);
+ col_ids[1] = v2_col_id;
+ var_info[1].time = v2_time;
+
+ if (emptyVar.empty() && CheckEmptyColumn(v2_col_id, v2_time)) {
+ emptyVar = v2_name;
}
}
if (num_var >= 3) {
diff --git a/DialogTools/VariableSettingsDlg.h b/DialogTools/VariableSettingsDlg.h
index cdb3570b1..9b53e5162 100644
--- a/DialogTools/VariableSettingsDlg.h
+++ b/DialogTools/VariableSettingsDlg.h
@@ -132,9 +132,31 @@ class VariableSettingsDlg: public wxDialog
public:
enum VarType {
univariate, bivariate, trivariate, quadvariate, rate_smoothed
- };
+ };
+
+ enum Style {
+ DEFAULT_STYLE = 0,
+ SHOW_WEIGHTS = 1, //0b00000001
+ SHOW_DISTANCE = 2, //0b00000010
+ SET_SECOND_FROM_FIRST = 4,
+ SET_FOURTH_FROM_THIRD = 8,
+ SHOW_TIME = 16,
+ ALLOW_STRING_IN_FIRST = 32,
+ ALLOW_STRING_IN_SECOND = 64,
+ ALLOW_STRING_IN_THIRD = 128,
+ ALLOW_STRING_IN_FOURTH = 256,
+ ALLOW_EMPTY_IN_FIRST = 512,
+ ALLOW_EMPTY_IN_SECOND = 1024
+ };
+
+ VariableSettingsDlg(Project* project, VarType v_type, int style,
+ const wxString& title=_("Variable Settings"),
+ const wxString& var1_title=_("First Variable (X)"),
+ const wxString& var2_title=_("Second Variable (Y)"),
+ const wxString& var3_title=_("Third Variable (Z)"),
+ const wxString& var4_title=_("Fourth Variable"));
- VariableSettingsDlg( Project* project, VarType v_type,
+ VariableSettingsDlg(Project* project, VarType v_type,
bool show_weights = false,
bool show_distance = false,
const wxString& title=_("Variable Settings"),
@@ -169,7 +191,10 @@ class VariableSettingsDlg: public wxDialog
void OnSpinCtrl( wxSpinEvent& event );
void OnOkClick( wxCommandEvent& event );
void OnCancelClick( wxCommandEvent& event );
-
+
+ bool IsFirstVariableEmpty();
+ bool IsSecondVariableEmpty();
+
std::vector var_info;
std::vector col_ids;
CatClassification::CatClassifType GetCatClassifType(); // for rate smoothed
@@ -180,7 +205,8 @@ class VariableSettingsDlg: public wxDialog
protected:
int m_theme; // for rate_smoothed
-
+ int style;
+
bool var1_str;
bool var2_str;
bool var3_str;
diff --git a/Explore/CatClassifManager.cpp b/Explore/CatClassifManager.cpp
index a5cc95ed7..71ac600bb 100644
--- a/Explore/CatClassifManager.cpp
+++ b/Explore/CatClassifManager.cpp
@@ -76,6 +76,7 @@ void CatClassifManager::RemoveClassifState(CatClassifState* ccs)
{
ccs->closeAndDeleteWhenEmpty();
classif_states.remove(ccs);
+ delete ccs;
}
bool CatClassifManager::VerifyAgainstTable()
diff --git a/Explore/CatClassifManager.h b/Explore/CatClassifManager.h
index 1a0154081..7220a56e6 100644
--- a/Explore/CatClassifManager.h
+++ b/Explore/CatClassifManager.h
@@ -34,16 +34,22 @@ class TableInterface;
class CatClassifManager : public TableStateObserver {
public:
CatClassifManager(TableInterface* table_int,
- TableState* table_state, CustomClassifPtree* cc_ptree);
+ TableState* table_state,
+ CustomClassifPtree* cc_ptree);
virtual ~CatClassifManager();
+
void GetTitles(std::vector& titles);
- CatClassifState* FindClassifState(const wxString& title);
- /** Create and return a new CatClassifState object and associate
+
+ CatClassifState* FindClassifState(const wxString& title);
+
+ /** Create and return a new CatClassifState object and associate
with a default variable db field name. If the name is blank,
then no default preview variable associated. */
CatClassifState* CreateNewClassifState(const CatClassifDef& cc_data);
- void RemoveClassifState(CatClassifState* ccs);
- bool VerifyAgainstTable();
+
+ void RemoveClassifState(CatClassifState* ccs);
+
+ bool VerifyAgainstTable();
/** Implementation of TableStateObserver interface */
virtual void update(TableState* o);
diff --git a/Explore/CatClassifState.cpp b/Explore/CatClassifState.cpp
index 1444338df..f1001cefc 100644
--- a/Explore/CatClassifState.cpp
+++ b/Explore/CatClassifState.cpp
@@ -27,6 +27,7 @@ CatClassifState::CatClassifState()
CatClassifState::~CatClassifState()
{
+
}
void CatClassifState::closeAndDeleteWhenEmpty()
@@ -44,8 +45,11 @@ void CatClassifState::registerObserver(CatClassifStateObserver* o)
void CatClassifState::removeObserver(CatClassifStateObserver* o)
{
- observers.remove(o);
- if (observers.size() == 0 && delete_self_when_empty) delete this;
+ observers.remove(o);
+
+ if (observers.size() == 0 && delete_self_when_empty) {
+ delete this;
+ }
}
void CatClassifState::notifyObservers()
diff --git a/Explore/CatClassifState.h b/Explore/CatClassifState.h
index 6a915e200..3c82ee877 100644
--- a/Explore/CatClassifState.h
+++ b/Explore/CatClassifState.h
@@ -43,7 +43,7 @@ class CatClassifState {
wxString GetTitle() { return cc_data.title; }
int GetNumberObservers() { return observers.size(); }
-private:
+protected:
/** The list of registered CatClassifStateObserver objects. */
std::list observers;
/** When the project is being closed, this is set to true so that
diff --git a/Explore/ConditionalClusterMapView.cpp b/Explore/ConditionalClusterMapView.cpp
index a0973ac35..17677e68b 100644
--- a/Explore/ConditionalClusterMapView.cpp
+++ b/Explore/ConditionalClusterMapView.cpp
@@ -71,10 +71,9 @@ num_categories(1),bin_bm(0),
bin_bg_map_pen(wxColor(200,200,200)),
bin_bg_map_brush(wxColor(200,200,200)),
cc_state_map(0),
-full_map_redraw_needed(true),
title(ttl)
{
-
+ full_map_redraw_needed = true;
}
ConditionalClusterMapCanvas::~ConditionalClusterMapCanvas()
@@ -599,6 +598,7 @@ void ConditionalClusterMapCanvas::PopulateCanvas()
shp->setPen(bin_bg_map_pen);
shp->setBrush(bin_bg_map_brush);
}
+ isResize = true;
full_map_redraw_needed = false;
}
} else {
diff --git a/Explore/ConditionalHistogramView.cpp b/Explore/ConditionalHistogramView.cpp
index d9060066e..159e201d6 100644
--- a/Explore/ConditionalHistogramView.cpp
+++ b/Explore/ConditionalHistogramView.cpp
@@ -65,9 +65,9 @@ ConditionalHistogramCanvas(wxWindow *parent,
const wxPoint& pos, const wxSize& size)
: ConditionalNewCanvas(parent, t_frame, project_s, v_info, col_ids,
false, true, pos, size),
-full_map_redraw_needed(true),
show_axes(true), scale_x_over_time(true), scale_y_over_time(true)
{
+ full_map_redraw_needed = true;
int hist_var_tms = data[HIST_VAR].shape()[0];
data_stats.resize(hist_var_tms);
@@ -524,6 +524,7 @@ void ConditionalHistogramCanvas::PopulateCanvas()
last_scale_trans.left_margin = virtual_screen_marg_left;
last_scale_trans.right_margin = virtual_screen_marg_right;
+ isResize = true;
ResizeSelectableShps();
}
diff --git a/Explore/ConditionalHistogramView.h b/Explore/ConditionalHistogramView.h
index c307abc29..2d8737e10 100644
--- a/Explore/ConditionalHistogramView.h
+++ b/Explore/ConditionalHistogramView.h
@@ -82,9 +82,7 @@ class ConditionalHistogramCanvas : public ConditionalNewCanvas {
void sel_shp_to_cell(int i, int& r, int& c, int& ival);
int cell_to_sel_shp_gen(int r, int c, int ival,
int cols, int ivals);
-
- bool full_map_redraw_needed;
-
+
static const int HIST_VAR; // histogram variable
// size = time_steps if HIST_VAR is time variant
diff --git a/Explore/ConditionalMapView.cpp b/Explore/ConditionalMapView.cpp
index 25218dbbb..04b5f83b0 100644
--- a/Explore/ConditionalMapView.cpp
+++ b/Explore/ConditionalMapView.cpp
@@ -64,9 +64,9 @@ ConditionalMapCanvas(wxWindow *parent,
num_categories(1),bin_bm(0),
bin_bg_map_pen(wxColor(200,200,200)),
bin_bg_map_brush(wxColor(200,200,200)),
-cc_state_map(0),
-full_map_redraw_needed(true)
+cc_state_map(0)
{
+ full_map_redraw_needed = true;
using namespace Shapefile;
SetCatType(CatClassification::no_theme);
@@ -101,7 +101,10 @@ full_map_redraw_needed(true)
ConditionalMapCanvas::~ConditionalMapCanvas()
{
- if (cc_state_map) cc_state_map->removeObserver(this);
+ if (cc_state_map) {
+ cc_state_map->removeObserver(this);
+ cc_state_map = NULL;
+ }
}
void ConditionalMapCanvas::DisplayRightClickMenu(const wxPoint& pos)
@@ -113,14 +116,94 @@ void ConditionalMapCanvas::DisplayRightClickMenu(const wxPoint& pos)
wxMenu* optMenu = wxXmlResource::Get()->LoadMenu("ID_COND_MAP_VIEW_MENU_OPTIONS");
AddTimeVariantOptionsToMenu(optMenu);
- TemplateCanvas::AppendCustomCategories(optMenu, project->GetCatClassifManager());
+ AppendCustomCategories(optMenu, project->GetCatClassifManager());
SetCheckMarks(optMenu);
-
+
+ if (var_info[VERT_VAR].is_hide == true) {
+ wxMenuItem* m = optMenu->FindItem(XRCID("ID_CAT_CLASSIF_B_MENU"));
+ wxMenu* smi = m->GetSubMenu();
+ GeneralWxUtils::EnableMenuRecursive(smi, false);
+ }
+ if (var_info[HOR_VAR].is_hide == true) {
+ wxMenuItem* m = optMenu->FindItem(XRCID("ID_CAT_CLASSIF_C_MENU"));
+ wxMenu* smi = m->GetSubMenu();
+ GeneralWxUtils::EnableMenuRecursive(smi, false);
+ }
+
template_frame->UpdateContextMenuItems(optMenu);
template_frame->PopupMenu(optMenu, pos + GetPosition());
template_frame->UpdateOptionMenuItems();
}
+void ConditionalMapCanvas::AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm)
+{
+ // search for ID_CAT_CLASSIF_A(B,C)_MENU submenus
+ const int num_sub_menus=3;
+ vector menu_id(num_sub_menus);
+ vector sub_menu_id(num_sub_menus);
+ vector base_id(num_sub_menus);
+ menu_id[0] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_A");
+ menu_id[1] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_B"); // conditional horizontal menu
+ menu_id[2] = XRCID("ID_NEW_CUSTOM_CAT_CLASSIF_C"); // conditional verticle menu
+ sub_menu_id[0] = XRCID("ID_CAT_CLASSIF_A_MENU");
+ sub_menu_id[1] = XRCID("ID_CAT_CLASSIF_B_MENU");
+ sub_menu_id[2] = XRCID("ID_CAT_CLASSIF_C_MENU");
+ base_id[0] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0;
+ base_id[1] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0;
+ base_id[2] = GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0;
+
+ for (int i=0; iFindItem(sub_menu_id[i]);
+ if (!smii) continue;
+ wxMenu* smi = smii->GetSubMenu();
+ if (!smi) continue;
+ int m_id = smi->FindItem(_("Custom Breaks"));
+ wxMenuItem* mi = smi->FindItem(m_id);
+ if (!mi) continue;
+
+ wxMenu* sm = mi->GetSubMenu();
+ // clean
+ wxMenuItemList items = sm->GetMenuItems();
+ for (int i=0; iDelete(items[i]);
+ }
+
+ sm->Append(menu_id[i], _("Create New Custom"), _("Create new custom categories classification."));
+ sm->AppendSeparator();
+
+ vector titles;
+ ccm->GetTitles(titles);
+ for (size_t j=0; jAppend(base_id[i]+j, titles[j]);
+ }
+
+ if (i==0) {
+ // regular map men
+ GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED,
+ &ConditionalMapCanvas::OnCustomCategoryClick, this, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0 + titles.size());
+ } else if (i==1) {
+ // conditional horizontal map menu
+ GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_B, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_B0 + titles.size());
+ } else if (i==2) {
+ // conditional verticle map menu
+ GdaFrame::GetGdaFrame()->Bind(wxEVT_COMMAND_MENU_SELECTED, &GdaFrame::OnCustomCategoryClick_C, GdaFrame::GetGdaFrame(), GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0, GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_C0 + titles.size());
+ }
+ }
+}
+
+void ConditionalMapCanvas::OnCustomCategoryClick(wxCommandEvent& event)
+{
+ int xrc_id = event.GetId();
+ CatClassifManager* ccm = project->GetCatClassifManager();
+ if (!ccm) return;
+ vector titles;
+ ccm->GetTitles(titles);
+ int idx = xrc_id - GdaConst::ID_CUSTOM_CAT_CLASSIF_CHOICE_A0;
+ if (idx < 0 || idx >= titles.size()) return;
+ wxString cc_title = titles[idx];
+
+ ((ConditionalMapFrame*) template_frame)->ChangeThemeType(CatClassification::custom, 4, cc_title);
+}
/**
* Overwrite TemplaceCanvas Scroll
*/
@@ -313,7 +396,7 @@ void ConditionalMapCanvas::ChangeCatThemeType(
if (cc_state_map) {
cc_state_map->removeObserver(this);
}
- cc_state_map = 0;
+ cc_state_map = NULL;
}
SetCatType(new_cat_theme);
VarInfoAttributeChange();
@@ -648,11 +731,13 @@ void ConditionalMapCanvas::PopulateCanvas()
{
int canvas_ts = cat_data.GetCurrentCanvasTmStep();
- if (!map_valid[canvas_ts]) full_map_redraw_needed = true;
+ if (map_valid[canvas_ts] == false) {
+ full_map_redraw_needed = true;
+ }
// Note: only need to delete selectable shapes if the cartogram
// relative positions change. Otherwise, just reuse.
- if (full_map_redraw_needed) {
+ if (full_map_redraw_needed == true) {
BOOST_FOREACH( GdaShape* shp, selectable_shps ) { delete shp; }
selectable_shps.clear();
}
@@ -661,12 +746,13 @@ void ConditionalMapCanvas::PopulateCanvas()
foreground_shps.clear();
if (map_valid[canvas_ts]) {
- if (full_map_redraw_needed) {
+ if (full_map_redraw_needed == true) {
CreateSelShpsFromProj(selectable_shps, project);
BOOST_FOREACH( GdaShape* shp, selectable_shps ) {
shp->setPen(bin_bg_map_pen);
shp->setBrush(bin_bg_map_brush);
}
+ isResize = true;
full_map_redraw_needed = false;
}
} else {
@@ -725,9 +811,9 @@ void ConditionalMapCanvas::CreateAndUpdateCategories()
{
cat_var_sorted.clear();
map_valid.resize(num_time_vals);
- for (int t=0; t& var_info,
- const vector& col_ids,
- const wxString& title, const wxPoint& pos,
- const wxSize& size, const long style)
-: ConditionalNewFrame(parent, project, var_info, col_ids, title, pos,
- size, style)
+ConditionalMapFrame::ConditionalMapFrame(wxFrame *parent, Project* project, const vector& var_info, const vector& col_ids, const wxString& title, const wxPoint& pos, const wxSize& size, const long style)
+: ConditionalNewFrame(parent, project, var_info, col_ids, title, pos, size, style)
{
wxLogMessage("Open ConditionalNewFrame.");
int width, height;
GetClientSize(&width, &height);
-
wxSplitterWindow* splitter_win = new wxSplitterWindow(this, wxID_ANY,
wxDefaultPosition, wxDefaultSize,
wxSP_3D|wxSP_LIVE_UPDATE|wxCLIP_CHILDREN);
diff --git a/Explore/ConditionalMapView.h b/Explore/ConditionalMapView.h
index 008d577dc..4da7fe509 100644
--- a/Explore/ConditionalMapView.h
+++ b/Explore/ConditionalMapView.h
@@ -71,6 +71,10 @@ class ConditionalMapCanvas : public ConditionalNewCanvas {
virtual void CreateAndUpdateCategories();
virtual void TimeSyncVariableToggle(int var_index);
+ virtual void AppendCustomCategories(wxMenu* menu, CatClassifManager* ccm);
+
+ void OnCustomCategoryClick(wxCommandEvent& event);
+
CatClassifDef cat_classif_def_map;
CatClassification::CatClassifType GetCatType();
void SetCatType(CatClassification::CatClassifType cc_type);
@@ -92,8 +96,6 @@ class ConditionalMapCanvas : public ConditionalNewCanvas {
wxPen bin_bg_map_pen;
wxBrush bin_bg_map_brush;
- bool full_map_redraw_needed;
-
static const int CAT_VAR; // theme variable
diff --git a/Explore/ConditionalNewView.cpp b/Explore/ConditionalNewView.cpp
index 333fea5ab..c4077e8b3 100644
--- a/Explore/ConditionalNewView.cpp
+++ b/Explore/ConditionalNewView.cpp
@@ -77,7 +77,8 @@ is_any_time_variant(false),
is_any_sync_with_global_time(false),
cc_state_vert(0),
cc_state_horiz(0),
-all_init(false)
+all_init(false),
+full_map_redraw_needed(true)
{
axis_display_precision = 1;
@@ -96,8 +97,9 @@ all_init(false)
else table_int->GetColData(col_ids[VERT_VAR], s_data[VERT_VAR]);
for (size_t i=0; iGetColData(col_ids[i], data[i]);
+ }
table_int->GetColUndefined(col_ids[i], data_undef[i]);
template_frame->AddGroupDependancy(var_info[i].name);
}
@@ -122,12 +124,16 @@ all_init(false)
else horiz_str_var_sorted[t].resize(num_obs);
for (int i=0; iremoveObserver(this);
+ }
cat_classif_def_vert = ccs->GetCatClassif();
cc_state_vert = ccs;
@@ -482,7 +504,10 @@ ChangeThemeType(int var_id,
cat_classif_def_horiz = cc_state_horiz->GetCatClassif();
}
} else {
- if (ccs) ccs->removeObserver(this);
+ if (ccs) {
+ ccs->removeObserver(this);
+ ccs = 0;
+ }
if (var_id == VERT_VAR) {
cc_state_vert = 0;
} else {
@@ -493,6 +518,7 @@ ChangeThemeType(int var_id,
VarInfoAttributeChange();
CreateAndUpdateCategories(var_id);
UserChangedCellCategories();
+ full_map_redraw_needed = true;
PopulateCanvas();
if (template_frame) {
template_frame->UpdateTitle();
@@ -739,6 +765,8 @@ ConditionalNewFrame(wxFrame *parent,
: TemplateFrame(parent, project, title, pos, size, style)
{
LOG_MSG("In ConditionalNewFrame::ConditionalNewFrame");
+
+ Connect(wxEVT_CLOSE_WINDOW, wxCloseEventHandler(ConditionalNewFrame::OnClose));
}
ConditionalNewFrame::~ConditionalNewFrame()
@@ -746,6 +774,13 @@ ConditionalNewFrame::~ConditionalNewFrame()
LOG_MSG("In ConditionalNewFrame::~ConditionalNewFrame");
}
+void ConditionalNewFrame::OnClose( wxCloseEvent& event )
+{
+ delete template_canvas;
+ Destroy();
+ event.Skip();
+}
+
void ConditionalNewFrame::MapMenus()
{
LOG_MSG("In ConditionalNewFrame::MapMenus");
diff --git a/Explore/ConditionalNewView.h b/Explore/ConditionalNewView.h
index 6bafc0459..abe06f8ca 100644
--- a/Explore/ConditionalNewView.h
+++ b/Explore/ConditionalNewView.h
@@ -99,6 +99,8 @@ class ConditionalNewCanvas
virtual void UpdateStatusBar();
protected:
+ bool full_map_redraw_needed;
+
TableInterface* table_int;
CatClassifState* cc_state_vert;
CatClassifState* cc_state_horiz;
@@ -182,7 +184,8 @@ class ConditionalNewFrame : public TemplateFrame {
CatClassification::CatClassifType new_theme,
int num_categories,
const wxString& cc_title = wxEmptyString);
-
+ void OnClose( wxCloseEvent& event );
+
DECLARE_EVENT_TABLE()
};
diff --git a/Explore/ConditionalScatterPlotView.cpp b/Explore/ConditionalScatterPlotView.cpp
index 2fe93189f..53a4985fe 100644
--- a/Explore/ConditionalScatterPlotView.cpp
+++ b/Explore/ConditionalScatterPlotView.cpp
@@ -59,7 +59,6 @@ ConditionalScatterPlotCanvas(wxWindow *parent,
const wxPoint& pos, const wxSize& size)
: ConditionalNewCanvas(parent, t_frame, project_s, v_info, col_ids,
false, true, pos, size),
-full_map_redraw_needed(true),
X(project_s->GetNumRecords()),
Y(project_s->GetNumRecords()),
XY_undef(project_s->GetNumRecords()),
@@ -68,6 +67,7 @@ display_slope_values(true),
show_linear_smoother(true),
show_lowess_smoother(false)
{
+ full_map_redraw_needed = true;
double x_max = var_info[IND_VAR].max_over_time;
double x_min = var_info[IND_VAR].min_over_time;
double y_max = var_info[DEP_VAR].max_over_time;
@@ -450,7 +450,7 @@ void ConditionalScatterPlotCanvas::ResizeSelectableShps(int virtual_scrn_w,
col_c = horiz_cat_data.categories[h_time].id_to_cat[i];
selectable_shps[i]->applyScaleTrans(st[row_c][col_c]);
}
-
+ isResize = true;
layer0_valid = false;
Refresh();
diff --git a/Explore/ConditionalScatterPlotView.h b/Explore/ConditionalScatterPlotView.h
index 7771b81eb..d8d32c517 100644
--- a/Explore/ConditionalScatterPlotView.h
+++ b/Explore/ConditionalScatterPlotView.h
@@ -78,7 +78,7 @@ class ConditionalScatterPlotCanvas : public ConditionalNewCanvas {
virtual void UpdateStatusBar();
protected:
- bool full_map_redraw_needed;
+
std::vector X;
std::vector Y;
std::vector XY_undef;
diff --git a/GdaConst.h b/GdaConst.h
index a6df5b925..db44ca061 100644
--- a/GdaConst.h
+++ b/GdaConst.h
@@ -144,6 +144,7 @@ class GdaConst {
static const int ID_PLOTS_PER_VIEW_OTHER = wxID_HIGHEST + 3100;
static const int ID_PLOTS_PER_VIEW_ALL = wxID_HIGHEST + 3200;
static const int ID_HISTOGRAM_CLASSIFICATION = wxID_HIGHEST + 3300;
+ static const int ID_CONDITION_CLASSIFICATION = wxID_HIGHEST + 3400;
static const int ID_CUSTOM_CAT_CLASSIF_CHOICE_A0 = wxID_HIGHEST + 4000;
static const int ID_CUSTOM_CAT_CLASSIF_CHOICE_B0 = wxID_HIGHEST + 4100;
diff --git a/GeoDa.cpp b/GeoDa.cpp
index 892cff35f..c001af0fb 100644
--- a/GeoDa.cpp
+++ b/GeoDa.cpp
@@ -2834,13 +2834,12 @@ void GdaFrame::OnShowConditionalMapView(wxCommandEvent& WXUNUSED(event) )
Project* p = GetProject();
if (!p) return;
- VariableSettingsDlg dlg(project_p, VariableSettingsDlg::trivariate, false, false,
+ int style = VariableSettingsDlg::ALLOW_STRING_IN_FIRST | VariableSettingsDlg::ALLOW_STRING_IN_SECOND | VariableSettingsDlg::ALLOW_EMPTY_IN_FIRST | VariableSettingsDlg::ALLOW_EMPTY_IN_SECOND;
+ VariableSettingsDlg dlg(project_p, VariableSettingsDlg::trivariate, style,
_("Conditional Map Variables"),
_("Horizontal Cells"),
_("Vertical Cells"),
- _("Map Theme"),
- "", false, false, false,
- true, true, false, false);
+ _("Map Theme"));
if (dlg.ShowModal() != wxID_OK) return;
diff --git a/Project.cpp b/Project.cpp
index 5a9f9e331..54f43f32c 100644
--- a/Project.cpp
+++ b/Project.cpp
@@ -189,10 +189,6 @@ Project::~Project()
if (project_conf) delete project_conf; project_conf=0;
// datasource* has been deleted in project_conf* layer*
datasource = 0;
- if (cat_classif_manager) {
- delete cat_classif_manager;
- cat_classif_manager=0;
- }
// Again, WeightsManInterface is not needed.
if (WeightsNewManager* o = dynamic_cast(w_man_int)) {
@@ -236,6 +232,11 @@ Project::~Project()
// clean up any global settings
MapCanvas::ResetEmptyFlag();
+ if (cat_classif_manager) {
+ delete cat_classif_manager;
+ cat_classif_manager=0;
+ }
+
wxLogMessage("Exiting Project::~Project");
}
diff --git a/ShapeOperations/WeightUtils.cpp b/ShapeOperations/WeightUtils.cpp
index 4a63ce081..1c8def1d3 100644
--- a/ShapeOperations/WeightUtils.cpp
+++ b/ShapeOperations/WeightUtils.cpp
@@ -857,7 +857,7 @@ GalElement* WeightUtils::Gwt2Gal(GwtElement* Gwt, long obs)
}
-void WeightUtils::LoadGwtInMan(WeightsManInterface* w_man_int, wxString filepath, TableInterface* table_int)
+void WeightUtils::LoadGwtInMan(WeightsManInterface* w_man_int, wxString filepath, TableInterface* table_int, wxString id_field)
{
int rows = table_int->GetNumberRows();
@@ -872,10 +872,13 @@ void WeightUtils::LoadGwtInMan(WeightsManInterface* w_man_int, wxString filepath
w->num_obs = rows;
w->wflnm = filepath;
w->gal = tempGal;
- w->id_field = "unknown";
+ w->id_field = id_field;
+ w->is_symmetric = true;
w->GetNbrStats();
wmi.num_obs = w->GetNumObs();
+ wmi.id_var = id_field;
+ wmi.SetSymmetric(w->is_symmetric);
wmi.SetMinNumNbrs(w->GetMinNumNbrs());
wmi.SetMaxNumNbrs(w->GetMaxNumNbrs());
wmi.SetMeanNumNbrs(w->GetMeanNumNbrs());
diff --git a/ShapeOperations/WeightUtils.h b/ShapeOperations/WeightUtils.h
index 19766d567..aea3a9820 100644
--- a/ShapeOperations/WeightUtils.h
+++ b/ShapeOperations/WeightUtils.h
@@ -35,7 +35,7 @@ namespace WeightUtils {
TableInterface* table_int);
GwtElement* ReadGwt(const wxString& w_fname, TableInterface* table_int);
GalElement* Gwt2Gal(GwtElement* Gwt, long obs);
- void LoadGwtInMan(WeightsManInterface* w_man_int, wxString filepath, TableInterface* table_int);
+ void LoadGwtInMan(WeightsManInterface* w_man_int, wxString filepath, TableInterface* table_int, wxString id_field);
}
#endif
diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp
index 25d06f109..8bb70eae8 100644
--- a/VarCalc/WeightsMetaInfo.cpp
+++ b/VarCalc/WeightsMetaInfo.cpp
@@ -92,6 +92,11 @@ void WeightsMetaInfo::SetToCustom(const wxString& idv)
id_var = idv;
}
+void WeightsMetaInfo::SetSymmetric(bool is_sym)
+{
+ sym_type = is_sym ? SYM_symmetric : SYM_unknown;
+}
+
void WeightsMetaInfo::SetToRook(const wxString& idv, long order_, bool inc_lower_orders_)
{
SetToDefaults();
diff --git a/VarCalc/WeightsMetaInfo.h b/VarCalc/WeightsMetaInfo.h
index 05756904d..7c0bdc319 100644
--- a/VarCalc/WeightsMetaInfo.h
+++ b/VarCalc/WeightsMetaInfo.h
@@ -162,7 +162,7 @@ struct WeightsMetaInfo
void SetMaxNumNbrs(int val);
void SetMeanNumNbrs(double val);
void SetMedianNumNbrs(double val);
-
+ void SetSymmetric(bool is_sym);
};
#endif
diff --git a/VarTools.h b/VarTools.h
index a9696af56..a0505f439 100644
--- a/VarTools.h
+++ b/VarTools.h
@@ -201,7 +201,8 @@ class Manager {
struct VarInfo {
VarInfo();
-
+
+ bool is_hide;
// Primary Attributes
wxString name;
bool is_time_variant;
@@ -235,15 +236,6 @@ struct VarInfo {
double min_over_time; // within time min/max range
double max_over_time; // within time min/max range
};
-
-struct VarState {
- bool is_any_time_variant;
- bool is_any_sync_with_global_time;
- int ref_var_index;
- int num_time_vals;
-};
-
-
/** Returns new reference variable index, or else -1 if no reference
diff --git a/Weights/DistUtils.cpp b/Weights/DistUtils.cpp
index 68dce194e..80afbc16b 100644
--- a/Weights/DistUtils.cpp
+++ b/Weights/DistUtils.cpp
@@ -9,6 +9,10 @@
#include
#include "DistUtils.h"
+#ifndef M_PI
+ #define M_PI 3.1415926535897932384626433832795
+#endif
+
using namespace GeoDa;
DistUtils::DistUtils(const std::vector >& input_data, int distance_metric)
diff --git a/kNN/ANN/ANN.h b/kNN/ANN/ANN.h
index c523608ed..00c4a145f 100755
--- a/kNN/ANN/ANN.h
+++ b/kNN/ANN/ANN.h
@@ -76,7 +76,8 @@
#ifdef DLL_EXPORTS
#define DLL_API __declspec(dllexport)
#else
- #define DLL_API __declspec(dllimport)
+ //#define DLL_API __declspec(dllimport)
+ #define DLL_API
#endif
//----------------------------------------------------------------------
// DLL_API is ignored for all other systems
diff --git a/version.h b/version.h
index 27619bad7..c06183662 100644
--- a/version.h
+++ b/version.h
@@ -2,10 +2,10 @@ namespace Gda {
const int version_major = 1;
const int version_minor = 12;
const int version_build = 1;
- const int version_subbuild = 179;
+ const int version_subbuild = 181;
const int version_year = 2018;
- const int version_month = 11;
- const int version_day = 26;
+ const int version_month = 12;
+ const int version_day = 6;
const int version_night = 0;
const int version_type = 2; // 0: alpha, 1: beta, 2: release
}