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 }