From f84c7810402402d16bbdc4ce733429755a8e23b3 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 18 Aug 2016 21:41:12 -0600 Subject: [PATCH 01/15] #456 propose fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for name with “blank space”, writing to weights file will automatically add quotes. Also add code to read these weights file with “quotes” file name. --- ShapeOperations/GalWeight.cpp | 43 ++++++++++++-- ShapeOperations/GwtWeight.cpp | 36 +++++++++-- ShapeOperations/WeightUtils.cpp | 102 ++++++++++++++++++++++++++++++-- SpatialIndAlgs.cpp | 11 +++- 4 files changed, 176 insertions(+), 16 deletions(-) diff --git a/ShapeOperations/GalWeight.cpp b/ShapeOperations/GalWeight.cpp index 1bdfdd2aa..76e0dc15d 100644 --- a/ShapeOperations/GalWeight.cpp +++ b/ShapeOperations/GalWeight.cpp @@ -246,6 +246,12 @@ bool GalWeight::SaveDIDWeights(Project* project, int num_obs, std::vector& id_vec) @@ -355,7 +367,14 @@ bool Gda::SaveGal(const GalElement* g, ofstream out; out.open(GET_ENCODED_FILENAME(final_fon)); if (!(out.is_open() && out.good())) return false; - + + wxString layer_name(_layer_name); + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } + size_t num_obs = (int) id_vec.size(); out << "0 " << num_obs << " " << layer_name; out << " " << id_var_name << endl; @@ -373,7 +392,7 @@ bool Gda::SaveGal(const GalElement* g, } bool Gda::SaveGal(const GalElement* g, - const wxString& layer_name, + const wxString& _layer_name, const wxString& ofname, const wxString& id_var_name, const std::vector& id_vec) @@ -388,7 +407,14 @@ bool Gda::SaveGal(const GalElement* g, ofstream out; out.open(GET_ENCODED_FILENAME(final_fon)); if (!(out.is_open() && out.good())) return false; - + + wxString layer_name(_layer_name); + + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } size_t num_obs = (int) id_vec.size(); out << "0 " << num_obs << " " << layer_name; out << " " << id_var_name << endl; @@ -407,7 +433,7 @@ bool Gda::SaveGal(const GalElement* g, bool Gda::SaveSpaceTimeGal(const GalElement* g, const std::vector& time_ids, - const wxString& layer_name, + const wxString& _layer_name, const wxString& ofname, const wxString& id_var_name, const std::vector& id_vec) @@ -426,6 +452,13 @@ bool Gda::SaveSpaceTimeGal(const GalElement* g, size_t num_obs = id_vec.size(); size_t num_t = time_ids.size(); size_t n = num_obs * num_t; + + wxString layer_name(_layer_name); + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } out << "0 " << n << " " << layer_name; out << " " << id_var_name << endl; diff --git a/ShapeOperations/GwtWeight.cpp b/ShapeOperations/GwtWeight.cpp index 6e54594eb..2239bd624 100644 --- a/ShapeOperations/GwtWeight.cpp +++ b/ShapeOperations/GwtWeight.cpp @@ -96,6 +96,12 @@ bool GwtWeight::SaveDIDWeights(Project* project, int num_obs, std::vector& id_vec) { using namespace std; - if (g == NULL || layer_name.IsEmpty() || ofname.IsEmpty() + if (g == NULL || _layer_name.IsEmpty() || ofname.IsEmpty() || id_vec.size() == 0) return false; wxFileName wx_fn(ofname); @@ -200,7 +212,14 @@ bool Gda::SaveGwt(const GwtElement* g, ofstream out; out.open(GET_ENCODED_FILENAME(final_ofn)); if (!(out.is_open() && out.good())) return false; - + + wxString layer_name(_layer_name); + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } + size_t num_obs = (int) id_vec.size(); out << "0 " << num_obs << " " << layer_name; out << " " << id_var_name << endl; @@ -218,13 +237,13 @@ bool Gda::SaveGwt(const GwtElement* g, bool Gda::SaveGwt(const GwtElement* g, - const wxString& layer_name, + const wxString& _layer_name, const wxString& ofname, const wxString& id_var_name, const std::vector& id_vec) { using namespace std; - if (g == NULL || layer_name.IsEmpty() || ofname.IsEmpty() + if (g == NULL || _layer_name.IsEmpty() || ofname.IsEmpty() || id_vec.size() == 0) return false; wxFileName wx_fn(ofname); @@ -234,6 +253,13 @@ bool Gda::SaveGwt(const GwtElement* g, out.open(GET_ENCODED_FILENAME(final_ofn)); if (!(out.is_open() && out.good())) return false; + wxString layer_name(_layer_name); + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } + size_t num_obs = (int) id_vec.size(); out << "0 " << num_obs << " " << layer_name; out << " " << id_var_name << endl; diff --git a/ShapeOperations/WeightUtils.cpp b/ShapeOperations/WeightUtils.cpp index 6dd8ff212..3f071d8cb 100644 --- a/ShapeOperations/WeightUtils.cpp +++ b/ShapeOperations/WeightUtils.cpp @@ -56,7 +56,32 @@ wxString WeightUtils::ReadIdField(const wxString& fname) wxInt64 num2 = 0; wxInt64 num_obs = 0; string dbf_name, t_key_field; - ss >> num1 >> num2 >> dbf_name >> t_key_field; + + + string line; + std::getline(ss, line); + wxString header(line); + + // detect if header contains string with empty space, which should be quoted + if (header.Contains("\"")) { + int start_quote = header.find("\""); + int end_quote = header.find("\"", start_quote + 1); + dbf_name = header.SubString(start_quote + 1, end_quote - 1); + t_key_field = header.SubString(end_quote + 1 + 1 /*1 for blank space */, + header.length()-1); + wxString nums = header.SubString(0, start_quote-1); + int break_pos = nums.find(" "); + wxString num1_str = nums.SubString(0, break_pos-1); + wxString num2_str = nums.SubString(break_pos+1, nums.length()-1); + num1_str.ToLongLong(&num1); + num2_str.ToLongLong(&num2); + + } else { + + ss >> num1 >> num2 >> dbf_name >> t_key_field; + } + + wxString key_field(t_key_field); if (num2 == 0) { key_field = ""; @@ -99,7 +124,31 @@ GalElement* WeightUtils::ReadGal(const wxString& fname, wxInt64 num2 = 0; wxInt64 num_obs = 0; string dbf_name, t_key_field; - ss >> num1 >> num2 >> dbf_name >> t_key_field; + + string line; + std::getline(ss, line); + wxString header(line); + + // detect if header contains string with empty space, which should be quoted + if (header.Contains("\"")) { + int start_quote = header.find("\""); + int end_quote = header.find("\"", start_quote + 1); + dbf_name = header.SubString(start_quote + 1, end_quote - 1); + t_key_field = header.SubString(end_quote + 1 + 1 /*1 for blank space */, + header.length()-1); + wxString nums = header.SubString(0, start_quote-1); + int break_pos = nums.find(" "); + wxString num1_str = nums.SubString(0, break_pos-1); + wxString num2_str = nums.SubString(break_pos+1, nums.length()-1); + num1_str.ToLongLong(&num1); + num2_str.ToLongLong(&num2); + + } else { + + ss >> num1 >> num2 >> dbf_name >> t_key_field; + } + + wxString key_field(t_key_field); if (num2 == 0) { use_rec_order = true; @@ -346,7 +395,29 @@ GalElement* WeightUtils::ReadGwtAsGal(const wxString& fname, wxInt64 num2 = 0; wxInt64 num_obs = 0; string dbf_name, t_key_field; - ss >> num1 >> num2 >> dbf_name >> t_key_field; + + string line; + std::getline(ss, line); + wxString header(line); + + // detect if header contains string with empty space, which should be quoted + if (header.Contains("\"")) { + int start_quote = header.find("\""); + int end_quote = header.find("\"", start_quote + 1); + dbf_name = header.SubString(start_quote + 1, end_quote - 1); + t_key_field = header.SubString(end_quote + 1 + 1 /*1 for blank space */, + header.length()-1); + wxString nums = header.SubString(0, start_quote-1); + int break_pos = nums.find(" "); + wxString num1_str = nums.SubString(0, break_pos-1); + wxString num2_str = nums.SubString(break_pos+1, nums.length()-1); + num1_str.ToLongLong(&num1); + num2_str.ToLongLong(&num2); + + } else { + + ss >> num1 >> num2 >> dbf_name >> t_key_field; + } wxString key_field(t_key_field); if (num2 == 0) { use_rec_order = true; @@ -576,7 +647,30 @@ GwtElement* WeightUtils::ReadGwt(const wxString& fname, wxInt64 num2 = 0; wxInt64 num_obs = 0; string dbf_name, t_key_field; - ss >> num1 >> num2 >> dbf_name >> t_key_field; + + string line; + std::getline(ss, line); + wxString header(line); + + // detect if header contains string with empty space, which should be quoted + if (header.Contains("\"")) { + int start_quote = header.find("\""); + int end_quote = header.find("\"", start_quote + 1); + dbf_name = header.SubString(start_quote + 1, end_quote - 1); + t_key_field = header.SubString(end_quote + 1 + 1 /*1 for blank space */, + header.length()-1); + wxString nums = header.SubString(0, start_quote-1); + int break_pos = nums.find(" "); + wxString num1_str = nums.SubString(0, break_pos-1); + wxString num2_str = nums.SubString(break_pos+1, nums.length()-1); + num1_str.ToLongLong(&num1); + num2_str.ToLongLong(&num2); + + } else { + + ss >> num1 >> num2 >> dbf_name >> t_key_field; + } + wxString key_field(t_key_field); if (num2 == 0) { use_rec_order = true; diff --git a/SpatialIndAlgs.cpp b/SpatialIndAlgs.cpp index 2f0fbb575..3aa58e9d3 100644 --- a/SpatialIndAlgs.cpp +++ b/SpatialIndAlgs.cpp @@ -1067,7 +1067,7 @@ GwtWeight* SpatialIndAlgs::knn_build(const rtree_pt_lonlat_t& rtree, int nn) } bool SpatialIndAlgs::write_gwt(const GwtWeight* W, - const wxString& layer_name, + const wxString& _layer_name, const wxString& ofname, const wxString& vname, const std::vector& id_vec) @@ -1077,7 +1077,7 @@ bool SpatialIndAlgs::write_gwt(const GwtWeight* W, if (!W) return false; const GwtElement* g = W->gwt; size_t num_obs = W->num_obs; - if (!g || layer_name.IsEmpty() || ofname.IsEmpty() + if (!g || _layer_name.IsEmpty() || ofname.IsEmpty() || id_vec.size() == 0 || num_obs != id_vec.size()) return false; wxFileName gwtfn(ofname); @@ -1087,6 +1087,13 @@ bool SpatialIndAlgs::write_gwt(const GwtWeight* W, out.open(GET_ENCODED_FILENAME(gwt_ofn)); if (!(out.is_open() && out.good())) return false; + wxString layer_name(_layer_name); + // if layer_name contains an empty space, the layer name should be + // braced with quotes "layer name" + if (layer_name.Contains(" ")) { + layer_name = "\"" + layer_name + "\""; + } + out << "0" << " " << num_obs << " " << layer_name; out << " " << vname.mb_str() << endl; From fcc114aa8c7465778a9abf288fc18f3604e00d9b Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 26 Aug 2016 18:04:56 -0500 Subject: [PATCH 02/15] #462 rook weights with precision threshold MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This fix is applied precision threshold to rook weights — when detect sharing edge, the precision threshold is not used in rook weights creation. --- ShapeOperations/PolysToContigWeights.cpp | 16 ++++++++-------- ShapeOperations/WeightUtils.cpp | 18 ++++++++++++++++-- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/ShapeOperations/PolysToContigWeights.cpp b/ShapeOperations/PolysToContigWeights.cpp index f5aa795a9..c9b71236a 100644 --- a/ShapeOperations/PolysToContigWeights.cpp +++ b/ShapeOperations/PolysToContigWeights.cpp @@ -235,7 +235,7 @@ class PolygonPartition void MakeSmallPartition(const int mX, const double Start, const double Stop); void MakeNeighbors(); - bool edge(PolygonPartition &p, const int host, const int guest); + bool edge(PolygonPartition &p, const int host, const int guest, double precision_threshold); int sweep(PolygonPartition & guest, bool is_queen, double precision_threshold=0.0); }; @@ -653,7 +653,7 @@ wxString getPointStr(const BasePoint& point) /** Method for detecting if an edge is shared between a host and guest polygon. */ bool PolygonPartition::edge(PolygonPartition &p, const int host, - const int guest) + const int guest, double precision_threshold) { using namespace Shapefile; @@ -662,17 +662,17 @@ bool PolygonPartition::edge(PolygonPartition &p, const int host, //BasePoint hostPoint = Points[ succ(host) ]; Point* hostPoint = this->GetPoint(succ(host)); - if (hostPoint->equals(guestPrev)) return true; + if (hostPoint->equals(guestPrev, precision_threshold)) return true; //BasePoint guestSucc= p.Points[ p.succ(guest) ]; Point* guestSucc= p.GetPoint(p.succ(guest)); - if (hostPoint->equals( guestSucc) ) return true; + if (hostPoint->equals( guestSucc, precision_threshold) ) return true; hostPoint= this->GetPoint( prev(host) ); - if (hostPoint->equals( guestSucc )) return true; + if (hostPoint->equals( guestSucc, precision_threshold )) return true; - if (hostPoint->equals( guestPrev )) return true; + if (hostPoint->equals( guestPrev, precision_threshold )) return true; return false; } @@ -754,8 +754,8 @@ int PolygonPartition::sweep(PolygonPartition & guest, bool is_queen, { if (pt->equals( GetPoint(host), precision_threshold) ) { - if (is_queen || edge(guest, host, dot)) { - pY.cleanup(pX, cell); + if (is_queen || edge(guest, host, dot, precision_threshold)) { + pY.cleanup(pX, cell); return 1; } } diff --git a/ShapeOperations/WeightUtils.cpp b/ShapeOperations/WeightUtils.cpp index 3f071d8cb..1314147d7 100644 --- a/ShapeOperations/WeightUtils.cpp +++ b/ShapeOperations/WeightUtils.cpp @@ -144,8 +144,22 @@ GalElement* WeightUtils::ReadGal(const wxString& fname, num2_str.ToLongLong(&num2); } else { - - ss >> num1 >> num2 >> dbf_name >> t_key_field; + + wxString num1_str = header.BeforeFirst(' '); + + header = header.AfterFirst(' '); + + wxString num2_str = header.BeforeFirst(' '); + + header = header.AfterFirst(' '); + + dbf_name = header.BeforeFirst(' '); + + t_key_field = header.AfterFirst(' '); + + + num1_str.ToLongLong(&num1); + num2_str.ToLongLong(&num2); } From 91a5218b86d510fb9ac4c4c9ddb1caf07796a8b6 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 26 Aug 2016 23:41:53 -0500 Subject: [PATCH 03/15] #466 distance weights X/Y centroids v.s. user selected Lat/Lon The user selections have been incorrectly read from memory, especially when NEW POLYID has been created --- DialogTools/CreatingWeightDlg.cpp | 17 ++++++++++++----- ShapeOperations/WeightUtils.cpp | 27 +++++++++++---------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 3cea4596e..fa6e389e4 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -191,8 +191,16 @@ void CreatingWeightDlg::OnCreateNewIdClick( wxCommandEvent& event ) if (dlg.ShowModal() == wxID_OK) { // We know that the new id has been added to the the table in memory - m_id_field->Insert(dlg.GetIdVarName(), 0); + //wxString new_id = dlg.GetIdVarName(); + //m_id_field->Insert(new_id, 0); + //m_id_field->SetSelection(0); + + col_id_map.clear(); + table_int->FillColIdMap(col_id_map); + + InitFields(); m_id_field->SetSelection(0); + EnableDistanceRadioButtons(m_id_field->GetSelection() != wxNOT_FOUND); EnableContiguityRadioButtons((m_id_field->GetSelection() != wxNOT_FOUND) && !project->IsTableOnlyProject()); UpdateCreateButtonState(); @@ -653,8 +661,8 @@ void CreatingWeightDlg::UpdateThresholdValues() } if (v1 != wxEmptyString || v2 != wxEmptyString) { if (v1 != wxEmptyString) { - int x_sel = (project->IsTableOnlyProject() ? - m_X->GetSelection() : m_X->GetSelection()-2); + // minus 2 is for and selection options in Dropdown + int x_sel = (project->IsTableOnlyProject() ? m_X->GetSelection() : m_X->GetSelection()-2); int col_id = col_id_map[x_sel]; int tm = 0; dist_tm_1 = -1; @@ -666,8 +674,7 @@ void CreatingWeightDlg::UpdateThresholdValues() table_int->GetColData(col_id, tm, m_XCOO); } if (v2 != wxEmptyString) { - int y_sel = (project->IsTableOnlyProject() ? - m_Y->GetSelection() : m_Y->GetSelection()-2); + int y_sel = (project->IsTableOnlyProject() ? m_Y->GetSelection() : m_Y->GetSelection()-2); int col_id = col_id_map[y_sel]; int tm = 0; dist_tm_2 = -1; diff --git a/ShapeOperations/WeightUtils.cpp b/ShapeOperations/WeightUtils.cpp index 1314147d7..59c40782e 100644 --- a/ShapeOperations/WeightUtils.cpp +++ b/ShapeOperations/WeightUtils.cpp @@ -78,7 +78,9 @@ wxString WeightUtils::ReadIdField(const wxString& fname) } else { - ss >> num1 >> num2 >> dbf_name >> t_key_field; + ss.clear(); + ss.seekg(0, ios::beg); // reset to beginning + ss >> num1 >> num2 >> dbf_name >> t_key_field; } @@ -145,21 +147,9 @@ GalElement* WeightUtils::ReadGal(const wxString& fname, } else { - wxString num1_str = header.BeforeFirst(' '); - - header = header.AfterFirst(' '); - - wxString num2_str = header.BeforeFirst(' '); - - header = header.AfterFirst(' '); - - dbf_name = header.BeforeFirst(' '); - - t_key_field = header.AfterFirst(' '); - - - num1_str.ToLongLong(&num1); - num2_str.ToLongLong(&num2); + ss.clear(); + ss.seekg(0, ios::beg); // reset to beginning + ss >> num1 >> num2 >> dbf_name >> t_key_field; } @@ -430,8 +420,11 @@ GalElement* WeightUtils::ReadGwtAsGal(const wxString& fname, } else { + ss.clear(); + ss.seekg(0, ios::beg); // reset to beginning ss >> num1 >> num2 >> dbf_name >> t_key_field; } + wxString key_field(t_key_field); if (num2 == 0) { use_rec_order = true; @@ -682,6 +675,8 @@ GwtElement* WeightUtils::ReadGwt(const wxString& fname, } else { + ss.clear(); + ss.seekg(0, ios::beg); // reset to beginning ss >> num1 >> num2 >> dbf_name >> t_key_field; } From 04e4278382dc727479b4d83d3846cee758216009 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Aug 2016 11:53:15 -0500 Subject: [PATCH 04/15] #464 read dist unit from projection data (for weights creation/management) --- DialogTools/CreatingWeightDlg.cpp | 32 ++++++++++++++++++++--------- DialogTools/CreatingWeightDlg.h | 4 +++- Explore/CorrelogramAlgs.cpp | 11 +++++++--- Project.cpp | 3 +++ Project.h | 1 + ShapeOperations/WeightsManPtree.cpp | 11 +++++----- VarCalc/WeightsMetaInfo.cpp | 14 +++++++++++-- VarCalc/WeightsMetaInfo.h | 6 +++++- 8 files changed, 59 insertions(+), 23 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index fa6e389e4..88a7b9e1a 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -304,17 +304,18 @@ void CreatingWeightDlg::OnCreateClick( wxCommandEvent& event ) { GwtWeight* Wp = 0; double t_val = m_threshold_val; - if (t_val <= 0) t_val = std::numeric_limits::min(); - wmi.SetToThres(id, dist_metric, dist_units, dist_values, - t_val, dist_var_1, dist_tm_1, - dist_var_2, dist_tm_2); + if (t_val <= 0) { + t_val = std::numeric_limits::min(); + } + wmi.SetToThres(id, dist_metric, dist_units, dist_units_str,dist_values, t_val, dist_var_1, dist_tm_1, dist_var_2, dist_tm_2); + if (m_is_arc && m_arc_in_km) { t_val /= GenGeomAlgs::one_mi_in_km; // convert km to mi } + if (t_val > 0) { using namespace SpatialIndAlgs; - Wp = thresh_build(m_XCOO, m_YCOO, t_val * m_thres_delta_factor, - m_is_arc, !m_arc_in_km); + Wp = thresh_build(m_XCOO, m_YCOO, t_val * m_thres_delta_factor, m_is_arc, !m_arc_in_km); if (!Wp || !Wp->gwt) { wxString m; m << "No weights file was created due to all observations "; @@ -335,15 +336,20 @@ void CreatingWeightDlg::OnCreateClick( wxCommandEvent& event ) case KNN: // k nn { - wmi.SetToKnn(id, dist_metric, dist_units, dist_values, m_kNN, dist_var_1, dist_tm_1, dist_var_2, dist_tm_2); + wmi.SetToKnn(id, dist_metric, dist_units, dist_units_str, dist_values, m_kNN, dist_var_1, dist_tm_1, dist_var_2, dist_tm_2); + if (m_kNN > 0 && m_kNN < m_num_obs) { GwtWeight* Wp = 0; Wp = SpatialIndAlgs::knn_build(m_XCOO, m_YCOO, m_kNN, dist_metric == WeightsMetaInfo::DM_arc, dist_units == WeightsMetaInfo::DU_mile); - if (!Wp->gwt) return; + + if (!Wp->gwt) + return; Wp->id_field = id; + WriteWeightFile(0, Wp->gwt, project->GetProjectTitle(), outputfile, id, wmi); if (Wp) delete Wp; done = true; + } else { wxString s; s << "Error: Maximum number of neighbors " << m_num_obs-1; @@ -921,7 +927,8 @@ void CreatingWeightDlg::InitDlg() m_thres_val_valid = false; m_threshold_val = 0.01; dist_metric = WeightsMetaInfo::DM_euclidean; - dist_units = WeightsMetaInfo::DU_mile; + dist_units = WeightsMetaInfo::DU_unspecified; + dist_units_str = project->project_unit; dist_values = WeightsMetaInfo::DV_centroids; dist_var_1 = ""; dist_tm_1 = -1; @@ -1062,7 +1069,12 @@ void CreatingWeightDlg::SetDistChoiceEuclid(bool update_sel) m_arc_in_km = false; dist_metric = WeightsMetaInfo::DM_euclidean; - dist_units = WeightsMetaInfo::DU_mile; + + // note: the projection information can be used (after version 1.8.10) + // to read the UNIT meta data. + dist_units_str = project->project_unit; + + dist_units = WeightsMetaInfo::DU_unspecified; } void CreatingWeightDlg::SetDistChoiceArcMiles(bool update_sel) diff --git a/DialogTools/CreatingWeightDlg.h b/DialogTools/CreatingWeightDlg.h index 5cda41fb2..f1b021eba 100644 --- a/DialogTools/CreatingWeightDlg.h +++ b/DialogTools/CreatingWeightDlg.h @@ -154,7 +154,9 @@ public TableStateObserver, public WeightsManStateObserver WeightsMetaInfo::DistanceMetricEnum dist_metric; WeightsMetaInfo::DistanceUnitsEnum dist_units; WeightsMetaInfo::DistanceValuesEnum dist_values; - + + wxString dist_units_str; + wxString dist_var_1; long dist_tm_1; wxString dist_var_2; diff --git a/Explore/CorrelogramAlgs.cpp b/Explore/CorrelogramAlgs.cpp index 57d188ce2..3db1f9134 100644 --- a/Explore/CorrelogramAlgs.cpp +++ b/Explore/CorrelogramAlgs.cpp @@ -181,8 +181,7 @@ bool CorrelogramAlgs::MakeCorrAllPairs(const std::vector& pts, size_t pc = 0; for (size_t i=0; i& pts, max_d = d; } Zdist[pc] = d; - if (calc_prods) Zprod[pc] = (Z[i]-mean)*(Z[j]-mean)/var; + if (calc_prods) + Zprod[pc] = (Z[i]-mean)*(Z[j]-mean)/var; ++pc; } } @@ -214,6 +214,11 @@ bool CorrelogramAlgs::MakeCorrAllPairs(const std::vector& pts, size_t ta_cnt = 0; for (size_t i=0, sz=Zdist.size(); i= num_bins) { b=num_bins-1; diff --git a/Project.cpp b/Project.cpp index 10a8e664e..b533b86f7 100644 --- a/Project.cpp +++ b/Project.cpp @@ -1320,6 +1320,9 @@ bool Project::CommonProjectInit() // convert projection to WGS84 by default if there is projection sourceSR = GetSpatialReference(); + if (sourceSR ) { + project_unit = sourceSR->GetAttrValue("UNIT"); + } // Initialize various managers frames_manager = new FramesManager; diff --git a/Project.h b/Project.h index 4fbb96ea7..8768d7356 100644 --- a/Project.h +++ b/Project.h @@ -197,6 +197,7 @@ class Project { /// main_data is the only public remaining attribute in Project Shapefile::Main main_data; OGRSpatialReference* sourceSR; + wxString project_unit; // ".gda" project file data wxString layer_title; // optional project::layers::layer::title field diff --git a/ShapeOperations/WeightsManPtree.cpp b/ShapeOperations/WeightsManPtree.cpp index 8eaf0f330..bf906bb77 100644 --- a/ShapeOperations/WeightsManPtree.cpp +++ b/ShapeOperations/WeightsManPtree.cpp @@ -174,12 +174,9 @@ void WeightsManPtree::ReadPtree(const boost::property_tree::ptree& pt, e.wmi.dist_units = WeightsMetaInfo::DU_km; } else if (s == "mile") { e.wmi.dist_units = WeightsMetaInfo::DU_mile; - } else if (s == "unspecified" || s.IsEmpty()) { + } else { e.wmi.dist_units = WeightsMetaInfo::DU_unspecified; - } else { - wxString msg("unrecognized value: "); - msg << s << " for key: " << key; - throw GdaException(msg.mb_str()); + e.wmi.dist_units_str = s; } } else if (key == "dist_values") { wxString s = v.second.data(); @@ -289,7 +286,9 @@ void WeightsManPtree::WritePtree(boost::property_tree::ptree& pt, sssub.put("dist_units", "km"); } else if (e.wmi.dist_units == WeightsMetaInfo::DU_mile) { sssub.put("dist_units", "mile"); - } + } else if (e.wmi.dist_units == WeightsMetaInfo::DU_unspecified) { + sssub.put("dist_units", e.wmi.dist_units_str); + } if (e.wmi.dist_values == WeightsMetaInfo::DV_centroids) { sssub.put("dist_values", "centroids"); } else if (e.wmi.dist_values == diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp index daef9b71e..111dda69d 100644 --- a/VarCalc/WeightsMetaInfo.cpp +++ b/VarCalc/WeightsMetaInfo.cpp @@ -75,6 +75,7 @@ void WeightsMetaInfo::SetToQueen(const wxString& idv, void WeightsMetaInfo::SetToThres(const wxString& idv, DistanceMetricEnum dist_metric_, DistanceUnitsEnum dist_units_, + wxString dist_units_str_, DistanceValuesEnum dist_values_, double threshold_val_, wxString dist_var1_, long dist_tm1_, @@ -86,6 +87,7 @@ void WeightsMetaInfo::SetToThres(const wxString& idv, sym_type = SYM_symmetric; dist_metric = dist_metric_; dist_units = dist_units_; + dist_units_str = dist_units_str_; dist_values = dist_values_; threshold_val = threshold_val_; if (!dist_var1_.IsEmpty()) { @@ -101,6 +103,7 @@ void WeightsMetaInfo::SetToThres(const wxString& idv, void WeightsMetaInfo::SetToKnn(const wxString& idv, DistanceMetricEnum dist_metric_, DistanceUnitsEnum dist_units_, + wxString dist_units_str_, DistanceValuesEnum dist_values_, long k, wxString dist_var1_, long dist_tm1_, @@ -112,6 +115,7 @@ void WeightsMetaInfo::SetToKnn(const wxString& idv, sym_type = SYM_asymmetric; dist_metric = dist_metric_; dist_units = dist_units_; + dist_units_str = dist_units_str_; dist_values = dist_values_; num_neighbors = k; if (!dist_var1_.IsEmpty()) { @@ -224,8 +228,14 @@ wxString WeightsMetaInfo::DistUnitsToStr() const return "km"; } else if (dist_units == DU_mile) { return "mile"; - } - return "unspecified"; + } else { + // dist_units == DU_unspecified + if (!dist_units_str.IsEmpty()) { + return dist_units_str; + } else { + return "unspecified"; + } + } } diff --git a/VarCalc/WeightsMetaInfo.h b/VarCalc/WeightsMetaInfo.h index 0fea36768..53653d57c 100644 --- a/VarCalc/WeightsMetaInfo.h +++ b/VarCalc/WeightsMetaInfo.h @@ -38,7 +38,7 @@ struct WeightsMetaInfo DM_unspecified, DM_euclidean, DM_arc }; enum DistanceUnitsEnum { - DU_unspecified, DU_km, DU_mile + DU_unspecified, DU_km, DU_mile }; WeightsMetaInfo(); @@ -51,6 +51,7 @@ struct WeightsMetaInfo void SetToThres(const wxString& id_var, DistanceMetricEnum dist_metric, DistanceUnitsEnum dist_units, + wxString dist_units_str, DistanceValuesEnum dist_values, double threshold_val, wxString dist_var_1 = "", long dist_tm_1 = -1, @@ -58,6 +59,7 @@ struct WeightsMetaInfo void SetToKnn(const wxString& id_var, DistanceMetricEnum dist_metric, DistanceUnitsEnum dist_units, + wxString dist_units_str, DistanceValuesEnum dist_values, long k, wxString dist_var_1 = "", long dist_tm_1 = -1, @@ -77,6 +79,8 @@ struct WeightsMetaInfo DistanceMetricEnum dist_metric; DistanceUnitsEnum dist_units; DistanceValuesEnum dist_values; + + wxString dist_units_str; wxString dist_var1; // x-coord wxString dist_var2; // y-coord From 644ab27b2387a61af74ff705c6bd04cbc465743a Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Aug 2016 12:15:13 -0500 Subject: [PATCH 05/15] #463 lower order included flag in project file The project file gives as true for first order rook and queen weights. While in and of itself this is harmless, it really should be set to false, since there is no inclusion of lower order for first order. --- ShapeOperations/WeightsManPtree.cpp | 2 +- VarCalc/WeightsMetaInfo.cpp | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/ShapeOperations/WeightsManPtree.cpp b/ShapeOperations/WeightsManPtree.cpp index bf906bb77..efecdc991 100644 --- a/ShapeOperations/WeightsManPtree.cpp +++ b/ShapeOperations/WeightsManPtree.cpp @@ -266,7 +266,7 @@ void WeightsManPtree::WritePtree(boost::property_tree::ptree& pt, WeightsMetaInfo::WT_rook ? "rook" : "queen")); sssub.put("order", e.wmi.order); - if (e.wmi.inc_lower_orders) { + if (e.wmi.inc_lower_orders == true) { sssub.put("inc_lower_orders", "true"); } else { sssub.put("inc_lower_orders", "false"); diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp index 111dda69d..cfc23ec90 100644 --- a/VarCalc/WeightsMetaInfo.cpp +++ b/VarCalc/WeightsMetaInfo.cpp @@ -30,7 +30,7 @@ void WeightsMetaInfo::SetToDefaults() filename = ""; sym_type = SYM_unknown; order = 1; - inc_lower_orders = true; + inc_lower_orders = false; dist_metric = DM_unspecified; dist_units = DU_unspecified; dist_values = DV_unspecified; @@ -57,7 +57,8 @@ void WeightsMetaInfo::SetToRook(const wxString& idv, sym_type = SYM_symmetric; order = order_; inc_lower_orders = inc_lower_orders_; - if (order < 2) inc_lower_orders = true; + //if (order < 2) + // inc_lower_orders = true; } void WeightsMetaInfo::SetToQueen(const wxString& idv, @@ -69,7 +70,8 @@ void WeightsMetaInfo::SetToQueen(const wxString& idv, sym_type = SYM_symmetric; order = order_; inc_lower_orders = inc_lower_orders_; - if (order < 2) inc_lower_orders = true; + //if (order < 2) + // inc_lower_orders = true; } void WeightsMetaInfo::SetToThres(const wxString& idv, From 56d964eb3a1e973efb2ba4517e9138d8a274b444 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Aug 2016 20:20:22 -0500 Subject: [PATCH 06/15] #460 always export WGS84 GeoJson --- DialogTools/ExportDataDlg.cpp | 35 ++++++++++- Project.cpp | 22 +++++-- ShapeOperations/OGRDataAdapter.cpp | 86 ++++++++++++-------------- ShapeOperations/OGRDatasourceProxy.cpp | 1 + 4 files changed, 92 insertions(+), 52 deletions(-) diff --git a/DialogTools/ExportDataDlg.cpp b/DialogTools/ExportDataDlg.cpp index 39e2c75df..954985dd0 100644 --- a/DialogTools/ExportDataDlg.cpp +++ b/DialogTools/ExportDataDlg.cpp @@ -32,6 +32,8 @@ #include #include +#include "ogr_srs_api.h" + #include "../Project.h" #include "../DataViewer/TableInterface.h" #include "../DataViewer/DbfTable.h" @@ -479,7 +481,9 @@ ExportDataDlg::CreateOGRLayer(wxString& ds_name, // for shp/dbf reading, we need to convert Main data to GdaShape first // this will spend some time, but keep the rest of code clean. // Note: potential speed/memory performance issue + vector selected_rows; + if ( project_p != NULL && geometries.empty() && !is_save_centroids ) { shape_type = Shapefile::NULL_SHAPE; int num_obs = project_p->main_data.records.size(); @@ -507,7 +511,7 @@ ExportDataDlg::CreateOGRLayer(wxString& ds_name, else if (project_p->main_data.header.shape_type == Shapefile::POLYGON) { PolygonContents* pc; for (int i=0; imain_data.records[i].contents_p; + pc = (PolygonContents*)project_p->main_data.records[i].contents_p; geometries.push_back(new GdaPolygon(pc)); } shape_type = Shapefile::POLYGON; @@ -524,10 +528,39 @@ ExportDataDlg::CreateOGRLayer(wxString& ds_name, selected_rows.push_back(i); } + /* + // explictly set SRS with EPSG information + wxString cstype = "PROJCS"; + if (poOutputSRS->IsGeographic() == 1) { + cstype = "GEOGCS"; + } + + wxString authname= poOutputSRS->GetAuthorityName(cstype.mb_str()); + wxString authCode = poOutputSRS->GetAuthorityCode(cstype.mb_str()); + + if (authname.IsEmpty()) { + int epsg = poOutputSRS->GetEPSGGeogCS(); + poOutputSRS->SetAuthority(cstype.mb_str(), "EPSG", epsg); + } + */ + // convert to OGR geometries vector ogr_geometries; OGRwkbGeometryType geom_type = OGRDataAdapter::GetInstance().MakeOGRGeometries(geometries, shape_type, ogr_geometries, selected_rows); + // NOTE: for GeoJSON, transform to WGS84 automatically + if (spatial_ref && (ds_name.EndsWith(".json") || ds_name.EndsWith(".geojson"))) { + int epsg = spatial_ref->GetEPSGGeogCS(); + if (epsg != 4326) { + OGRSpatialReference wgs84_ref; + wgs84_ref.importFromEPSG(4326); + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( spatial_ref, &wgs84_ref ); + for (size_t i=0; i < ogr_geometries.size(); i++) { + ogr_geometries[i]->transform(poCT); + } + } + } + // take care of empty layer name if (layer_name.empty()) { layer_name = table_p ? table_p->GetTableName() : "NO_NAME"; diff --git a/Project.cpp b/Project.cpp index b533b86f7..ac003786e 100644 --- a/Project.cpp +++ b/Project.cpp @@ -31,6 +31,8 @@ #include #include #include + +#include "ogr_srs_api.h" #include "logger.h" #include "FramesManager.h" #include "SaveButtonManager.h" @@ -462,6 +464,7 @@ void Project::SaveDataSourceAs(const wxString& new_ds_name, bool is_update) { LOG_MSG("Entering Project::SaveDataSourceAs"); LOG_MSG("New Datasource Name:" + new_ds_name); + vector geometries; try { // SaveAs only to same datasource @@ -494,12 +497,21 @@ void Project::SaveDataSourceAs(const wxString& new_ds_name, bool is_update) for (size_t i=0; iGetNumberRows(); i++) { selected_rows.push_back(i); } - + + // Create in-memory OGR geometries vector ogr_geometries; - OGRwkbGeometryType geom_type = - OGRDataAdapter::GetInstance().MakeOGRGeometries(geometries, shape_type, - ogr_geometries, - selected_rows); + OGRwkbGeometryType geom_type = OGRDataAdapter::GetInstance().MakeOGRGeometries(geometries, shape_type, ogr_geometries, selected_rows); + + // NOTE: for GeoJSON, automatically transform to WGS84 + if (spatial_ref && ds_type == GdaConst::ds_geo_json) { + OGRSpatialReference wgs84_ref; + wgs84_ref.importFromEPSG(4326); + OGRCoordinateTransformation *poCT = OGRCreateCoordinateTransformation( spatial_ref, &wgs84_ref ); + for (size_t i=0; i < ogr_geometries.size(); i++) { + ogr_geometries[i]->transform(poCT); + } + } + // Start saving int prog_n_max = 0; diff --git a/ShapeOperations/OGRDataAdapter.cpp b/ShapeOperations/OGRDataAdapter.cpp index 1ecf79f72..8863e4727 100644 --- a/ShapeOperations/OGRDataAdapter.cpp +++ b/ShapeOperations/OGRDataAdapter.cpp @@ -214,66 +214,60 @@ OGRDataAdapter::MakeOGRGeometries(vector& geometries, ogr_geometries.push_back(pt); } else if ( shape_type == Shapefile::POLYGON ) { + GdaPolygon* poly = (GdaPolygon*) geometries[id]; if (poly->isNull()) { - OGRPolygon* polygon = - (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); - //OGRLinearRing* ring = - //(OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); + OGRPolygon* polygon = (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); + //OGRLinearRing* ring =(OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); //ring->closeRings(); //polygon->addRingDirectly(ring); ogr_geometries.push_back(polygon); + } else { int numParts = poly->n_count; int numPoints = poly->n; double x, y; if ( numParts == 1 ) { - eGType = wkbPolygon; - OGRPolygon* polygon = - (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); - OGRLinearRing* ring = - (OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); - for ( int j = 0; j < numPoints; j++ ) { - if ( poly->points_o != NULL ) { - // for created centroids or other geometries, the actual - // points are stored in points_o wxRealPoint[]. - // Note: GdaPolygon::count[] constantly has size = 1 in - // current design, see GdaPolygon class - x = poly->points_o[j].x; - y = poly->points_o[j].y; - } else { - x = poly->pc->points[j].x; - y = poly->pc->points[j].y; - } - ring->addPoint(x,y); - } - ring->closeRings(); - polygon->addRingDirectly(ring); - ogr_geometries.push_back(polygon); - - } else if ( numParts > 1 ) { - eGType = wkbMultiPolygon; - OGRMultiPolygon* multi_polygon = - (OGRMultiPolygon*)OGRGeometryFactory::createGeometry(wkbMultiPolygon); - for ( int num_part = 0; num_part < numParts; num_part++ ) { - OGRPolygon* polygon = - (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); - OGRLinearRing* ring = - (OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); - vector startIndexes = poly->pc->parts; - startIndexes.push_back(numPoints); - for ( size_t j = startIndexes[num_part]; - j < startIndexes[num_part+1]; j++ ) { - - x = poly->pc->points[j].x; - y = poly->pc->points[j].y; + eGType = wkbPolygon; + OGRPolygon* polygon = (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); + OGRLinearRing* ring = (OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); + for ( int j = 0; j < numPoints; j++ ) { + if ( poly->points_o != NULL ) { + // for created centroids or other geometries, the actual + // points are stored in points_o wxRealPoint[]. + // Note: GdaPolygon::count[] constantly has size = 1 in + // current design, see GdaPolygon class + x = poly->points_o[j].x; + y = poly->points_o[j].y; + } else { + x = poly->pc->points[j].x; + y = poly->pc->points[j].y; + } ring->addPoint(x,y); } ring->closeRings(); polygon->addRingDirectly(ring); - multi_polygon->addGeometryDirectly(polygon); - } - ogr_geometries.push_back(multi_polygon); + ogr_geometries.push_back(polygon); + + } else if ( numParts > 1 ) { + eGType = wkbMultiPolygon; + OGRMultiPolygon* multi_polygon = (OGRMultiPolygon*)OGRGeometryFactory::createGeometry(wkbMultiPolygon); + for ( int num_part = 0; num_part < numParts; num_part++ ) { + OGRPolygon* polygon = (OGRPolygon*)OGRGeometryFactory::createGeometry(wkbPolygon); + OGRLinearRing* ring = (OGRLinearRing*)OGRGeometryFactory::createGeometry(wkbLinearRing); + vector startIndexes = poly->pc->parts; + startIndexes.push_back(numPoints); + for ( size_t j = startIndexes[num_part]; j < startIndexes[num_part+1]; j++ ) { + + x = poly->pc->points[j].x; + y = poly->pc->points[j].y; + ring->addPoint(x,y); + } + ring->closeRings(); + polygon->addRingDirectly(ring); + multi_polygon->addGeometryDirectly(polygon); + } + ogr_geometries.push_back(multi_polygon); } } } diff --git a/ShapeOperations/OGRDatasourceProxy.cpp b/ShapeOperations/OGRDatasourceProxy.cpp index 52fea4e4a..023368354 100644 --- a/ShapeOperations/OGRDatasourceProxy.cpp +++ b/ShapeOperations/OGRDatasourceProxy.cpp @@ -338,6 +338,7 @@ OGRDatasourceProxy::CreateLayer(string layer_name, } OGRSpatialReference *poOutputSRS = spatial_ref; + // PRECISION is for database e.g. MSSQL // LAUNDER is for database: rename desired field name From a6bc741be821fcf3bdb9bd07ffe5306754732e1b Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 29 Aug 2016 20:34:07 -0500 Subject: [PATCH 07/15] #457 avg charts black line dotted MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit also update hover text of black line to “all obs mean=” --- Explore/LineChartCanvas.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Explore/LineChartCanvas.cpp b/Explore/LineChartCanvas.cpp index 13ba44f2c..dbb659946 100644 --- a/Explore/LineChartCanvas.cpp +++ b/Explore/LineChartCanvas.cpp @@ -260,7 +260,7 @@ void LineChartCanvas::UpdateStatusBar() if (c.pointWithin(sel1)) { if (!s.IsEmpty()) s << ", "; if (!time_inv) s << table_int->GetTimeString(t) << " "; - s << "mean=" << lcs.Y_avg[t]; + s << "all obs mean=" << lcs.Y_avg[t]; } } for (size_t t=0, tms=sel_circs.size(); tsetPen(*wxBLACK_PEN); + p->setPen(wxPen(*wxBLACK, 1, wxSHORT_DASH)); background_shps.push_back(p); for (size_t t=0; t Date: Mon, 29 Aug 2016 20:34:51 -0500 Subject: [PATCH 08/15] update version 1.8.11.1 --- version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version.h b/version.h index eee789ed4..b6e8d9ac8 100644 --- a/version.h +++ b/version.h @@ -1,11 +1,11 @@ namespace Gda { const int version_major = 1; const int version_minor = 8; - const int version_build = 10; - const int version_subbuild = 0; + const int version_build = 11; + const int version_subbuild = 1; const int version_year = 2016; - const int version_month = 7; - const int version_day = 14; + const int version_month = 8; + const int version_day = 29; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 1f878e1c38708194fa8d11116b11f4350e9d3529 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 30 Aug 2016 11:27:35 -0500 Subject: [PATCH 09/15] #465 nodebug flag reset --- BuildTools/macosx/auto_build.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BuildTools/macosx/auto_build.sh b/BuildTools/macosx/auto_build.sh index 0ace3869d..29e26ec26 100755 --- a/BuildTools/macosx/auto_build.sh +++ b/BuildTools/macosx/auto_build.sh @@ -11,7 +11,7 @@ git pull cd ~/geoda_trunk/o rm * cd ~/geoda_trunk/BuildTools/macosx -./build.sh $CPU $DEBUG +./build.sh $CPU $NODEBUG cd ~/Dropbox/yoursway-create-dmg ./geoda.sh $VERSION mv GeoDa$VERSION-Installer.dmg ~/Dropbox From cbd27e6d3d34af38ada5aa13032fd044d634927c Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 31 Aug 2016 14:18:20 -0500 Subject: [PATCH 10/15] #459 implementation of CSV type specify dialog --- .gitignore | 6 + .../macosx/GeoDa.xcodeproj/project.pbxproj | 6 + DialogTools/ConnectDatasourceDlg.cpp | 32 +-- DialogTools/CsvFieldConfDlg.cpp | 218 ++++++++++++++++++ DialogTools/CsvFieldConfDlg.h | 56 +++++ 5 files changed, 304 insertions(+), 14 deletions(-) create mode 100644 DialogTools/CsvFieldConfDlg.cpp create mode 100644 DialogTools/CsvFieldConfDlg.h diff --git a/.gitignore b/.gitignore index 74affe661..ea2cae4da 100644 --- a/.gitignore +++ b/.gitignore @@ -53,3 +53,9 @@ rc/Drop-Files-Here-extra-black.png *.opensdf *.exe BuildTools/windows/logger.txt + +BuildTools/.DS_Store + +.DS_Store + +*.DS_Store diff --git a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj index d04595296..edb1228b8 100644 --- a/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj +++ b/BuildTools/macosx/GeoDa.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ A11F1B821850437A006F5F98 /* OGRTableOperation.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A11F1B801850437A006F5F98 /* OGRTableOperation.cpp */; }; A12E0F4F1705087A00B6059C /* OGRDataAdapter.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A12E0F4E1705087A00B6059C /* OGRDataAdapter.cpp */; }; A13B6B9418760CF100F93ACF /* SaveAsDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */; }; + A14C496F1D76174000D9831C /* CsvFieldConfDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */; }; A16BA470183D626200D3B7DA /* DatasourceDlg.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */; }; A186F0A11C16508A00AEBA13 /* GdaCartoDB.cpp in Sources */ = {isa = PBXBuildFile; fileRef = A186F09F1C16508A00AEBA13 /* GdaCartoDB.cpp */; }; A19F51501756A11E006E31B4 /* plugins in Resources */ = {isa = PBXBuildFile; fileRef = A19F514D1756A11E006E31B4 /* plugins */; }; @@ -233,6 +234,8 @@ A12E0F4E1705087A00B6059C /* OGRDataAdapter.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = OGRDataAdapter.cpp; sourceTree = ""; }; A13B6B9218760CF100F93ACF /* SaveAsDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SaveAsDlg.h; sourceTree = ""; }; A13B6B9318760CF100F93ACF /* SaveAsDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SaveAsDlg.cpp; sourceTree = ""; }; + A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CsvFieldConfDlg.cpp; sourceTree = ""; }; + A14C496E1D76174000D9831C /* CsvFieldConfDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CsvFieldConfDlg.h; sourceTree = ""; }; A16BA46E183D626200D3B7DA /* DatasourceDlg.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = DatasourceDlg.cpp; sourceTree = ""; }; A16BA46F183D626200D3B7DA /* DatasourceDlg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DatasourceDlg.h; sourceTree = ""; }; A171FBFE1792332A000DD5A0 /* GdaException.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GdaException.h; sourceTree = ""; }; @@ -750,6 +753,8 @@ DD7974FE0F1D296F00496A84 /* DialogTools */ = { isa = PBXGroup; children = ( + A14C496D1D76174000D9831C /* CsvFieldConfDlg.cpp */, + A14C496E1D76174000D9831C /* CsvFieldConfDlg.h */, A1EBC88D1CD2B2FD001DCFE9 /* AutoUpdateDlg.cpp */, A1EBC88E1CD2B2FD001DCFE9 /* AutoUpdateDlg.h */, A1AC05BD1C8645F300B6FE5F /* AdjustYAxisDlg.cpp */, @@ -1369,6 +1374,7 @@ DDEA3CBE193CEE5C0028B746 /* GdaLexer.cpp in Sources */, DDEA3CBF193CEE5C0028B746 /* GdaParser.cpp in Sources */, DDEA3D01193D17130028B746 /* CalculatorDlg.cpp in Sources */, + A14C496F1D76174000D9831C /* CsvFieldConfDlg.cpp in Sources */, DDA4F0A4196311A9007645E2 /* WeightsMetaInfo.cpp in Sources */, DDA4F0AD196315AF007645E2 /* WeightUtils.cpp in Sources */, DD817EA819676AF100228B0A /* WeightsManState.cpp in Sources */, diff --git a/DialogTools/ConnectDatasourceDlg.cpp b/DialogTools/ConnectDatasourceDlg.cpp index 5ed67d39b..2ba3b853e 100644 --- a/DialogTools/ConnectDatasourceDlg.cpp +++ b/DialogTools/ConnectDatasourceDlg.cpp @@ -33,6 +33,7 @@ #include #include +#include "../DialogTools/CsvFieldConfDlg.h" #include "../DataViewer/DataSource.h" #include "../ShapeOperations/OGRDataAdapter.h" #include "../GenUtils.h" @@ -58,8 +59,6 @@ class DnDFile : public wxFileDropTarget bool DnDFile::OnDropFiles(wxCoord, wxCoord, const wxArrayString& filenames) { size_t nFiles = filenames.GetCount(); - //wxString str; - //str.Printf( wxT("%d files dropped"), (int)nFiles); if (m_pOwner != NULL && nFiles > 0) { @@ -83,8 +82,7 @@ END_EVENT_TABLE() using namespace std; -ConnectDatasourceDlg::ConnectDatasourceDlg(wxWindow* parent, const wxPoint& pos, - const wxSize& size) +ConnectDatasourceDlg::ConnectDatasourceDlg(wxWindow* parent, const wxPoint& pos, const wxSize& size) :datasource(0) { // init controls defined in parent class @@ -98,8 +96,7 @@ ConnectDatasourceDlg::ConnectDatasourceDlg(wxWindow* parent, const wxPoint& pos, m_drag_drop_box->SetDropTarget(new DnDFile(this)); - Bind(wxEVT_COMMAND_MENU_SELECTED, &ConnectDatasourceDlg::BrowseDataSource, - this, DatasourceDlg::ID_DS_START, ID_DS_START + ds_names.Count()); + Bind(wxEVT_COMMAND_MENU_SELECTED, &ConnectDatasourceDlg::BrowseDataSource, this, DatasourceDlg::ID_DS_START, ID_DS_START + ds_names.Count()); } ConnectDatasourceDlg::~ConnectDatasourceDlg() @@ -194,6 +191,7 @@ void ConnectDatasourceDlg::OnOkClick( wxCommandEvent& event ) { LOG_MSG("Entering ConnectDatasourceDlg::OnOkClick"); try { + // Open GeoDa project file direclty if (ds_file_path.GetExt().Lower() == "gda") { GdaFrame* gda_frame = GdaFrame::GetGdaFrame(); if (gda_frame) { @@ -202,8 +200,16 @@ void ConnectDatasourceDlg::OnOkClick( wxCommandEvent& event ) } return; } + + // For csv file, if no csvt file, pop-up a field definition dialog and create a csvt file + if (ds_file_path.GetExt().Lower() == "csv") { + wxString csv_path = ds_file_path.GetFullPath(); + CsvFieldConfDlg csvDlg(this, csv_path); + csvDlg.ShowModal(); + } CreateDataSource(); + // Check to make sure to get a layer name wxString layername; int datasource_type = m_ds_notebook->GetSelection(); @@ -238,10 +244,12 @@ void ConnectDatasourceDlg::OnOkClick( wxCommandEvent& event ) return; } - if (layername.IsEmpty()) return; + if (layername.IsEmpty()) + return; // At this point, there is a valid datasource and layername. - if (layer_name.IsEmpty()) layer_name = layername; + if (layer_name.IsEmpty()) + layer_name = layername; EndDialog(wxID_OK); @@ -298,8 +306,7 @@ IDataSource* ConnectDatasourceDlg::CreateDataSource() PromptDSLayers(datasource); if (layer_name.IsEmpty()) { throw GdaException( - wxString("Layer/Table name could not be empty. Please select" - " a layer/table.").mb_str()); + wxString("Layer/Table name could not be empty. Please select a layer/table.").mb_str()); } } @@ -322,10 +329,7 @@ IDataSource* ConnectDatasourceDlg::CreateDataSource() else if (cur_sel == DBTYPE_MYSQL) ds_type = GdaConst::ds_mysql; //else if (cur_sel == 4) ds_type = GdaConst::ds_ms_sql; else { - wxString msg = "The selected database driver is not supported " - "on this platform. Please check GeoDa website " - "for more information about database support " - " and connection."; + wxString msg = "The selected database driver is not supported on this platform. Please check GeoDa website for more information about database support and connection."; throw GdaException(msg.mb_str()); } diff --git a/DialogTools/CsvFieldConfDlg.cpp b/DialogTools/CsvFieldConfDlg.cpp new file mode 100644 index 000000000..0c2db5f0d --- /dev/null +++ b/DialogTools/CsvFieldConfDlg.cpp @@ -0,0 +1,218 @@ +/** + * GeoDa TM, Copyright (C) 2011-2015 by Luc Anselin - all rights reserved + * + * This file is part of GeoDa. + * + * GeoDa is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GeoDa is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "stdio.h" +#include +#include + + +#include "../logger.h" +#include "../GeneralWxUtils.h" +#include "../GdaException.h" +#include "../ShapeOperations/OGRDataAdapter.h" +#include "CsvFieldConfDlg.h" + +using namespace std; + + +CsvFieldConfDlg::CsvFieldConfDlg(wxWindow* parent, + wxString _filepath, + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size ) +: wxDialog(parent, id, title, pos, size) +{ + + LOG_MSG("Entering CsvFieldConfDlg::CsvFieldConfDlg(..)"); + + filepath = _filepath; + wxTextFile tfile; + tfile.Open(filepath); + + // read the first line + wxString str = tfile.GetFirstLine(); + wxStringTokenizer tokenizer(str, ","); + while ( tokenizer.HasMoreTokens() ) + { + wxString token = tokenizer.GetNextToken(); + col_names.push_back(token); + } + + int n_rows = col_names.size(); + int n_cols = 2; // 1 Var name 2 type + + + wxPanel* panel = new wxPanel(this); + panel->SetBackgroundColour(*wxWHITE); + + wxStaticText* lbl = new wxStaticText(panel, wxID_ANY, "Please Specify Data Type for Each Data Column."); + + wxBoxSizer* lbl_box = new wxBoxSizer(wxVERTICAL); + lbl_box->AddSpacer(5); + lbl_box->Add(lbl, 1, wxALIGN_CENTER | wxEXPAND |wxALL, 10); + + fieldGrid = new wxGrid(this, wxID_ANY, wxDefaultPosition, wxSize(300,-1)); + fieldGrid->CreateGrid(n_rows, n_cols, wxGrid::wxGridSelectRows); + fieldGrid->SetColLabelValue(0, "Column Name"); + fieldGrid->SetColLabelValue(1, "Data Type"); + + wxBoxSizer* grid_box = new wxBoxSizer(wxVERTICAL); + grid_box->AddSpacer(5); + grid_box->Add(fieldGrid, 1, wxALIGN_CENTER | wxEXPAND |wxALL, 10); + + wxButton* btn_cancel= new wxButton(panel, wxID_ANY, "Cancel", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + wxButton* btn_update= new wxButton(panel, wxID_ANY, "OK", wxDefaultPosition, wxDefaultSize, wxBU_EXACTFIT); + + wxBoxSizer* btn_box = new wxBoxSizer(wxHORIZONTAL); + btn_box->Add(btn_cancel, 1, wxALIGN_CENTER |wxEXPAND| wxALL, 10); + btn_box->Add(btn_update, 1, wxALIGN_CENTER | wxEXPAND | wxALL, 10); + + wxBoxSizer* box = new wxBoxSizer(wxVERTICAL); + box->Add(lbl_box, 0, wxALIGN_TOP | wxEXPAND | wxLEFT | wxRIGHT | wxTOP, 10); + box->Add(grid_box, 0, wxALIGN_CENTER| wxEXPAND| wxRIGHT | wxTOP, 0); + box->Add(btn_box, 0, wxALIGN_CENTER| wxLEFT | wxRIGHT | wxTOP, 20); + + panel->SetSizerAndFit(box); + + wxBoxSizer* sizerAll = new wxBoxSizer(wxVERTICAL); + sizerAll->Add(panel, 1, wxEXPAND|wxALL); + SetSizer(sizerAll); + SetAutoLayout(true); + + SetParent(parent); + SetPosition(pos); + Centre(); + + + btn_update->Connect(wxEVT_BUTTON, wxCommandEventHandler(CsvFieldConfDlg::OnOkClick), NULL, this); + btn_cancel->Connect(wxEVT_BUTTON, wxCommandEventHandler(CsvFieldConfDlg::OnCancelClick), NULL, this); + + + vector types; + wxString csvt_path = filepath + "t"; + + if (wxFileExists(csvt_path)) { + // load data type from csvt file + wxTextFile csvt_file; + csvt_file.Open(csvt_path); + + // read the first line + wxString str = csvt_file.GetFirstLine(); + wxStringTokenizer tokenizer(str, ","); + + while ( tokenizer.HasMoreTokens() ) + { + wxString token = tokenizer.GetNextToken().Upper(); + if (token.Contains("INTEGER")) { + types.push_back("Integer"); + } else if (token.Contains("REAL")) { + types.push_back("Real"); + } else { + types.push_back("String"); + } + } + + } else { + // read second line, guess the type + str = tfile.GetNextLine(); + wxStringTokenizer tokenizer1(str, ","); + while ( tokenizer1.HasMoreTokens() ) + { + wxString token = tokenizer1.GetNextToken(); + + wxString val = token.Trim(true).Trim(false); + double d_val = 0; + + if (val.IsNumber()) { + types.push_back("Integer"); + } else if (val.ToDouble(&d_val)) { + types.push_back("Real"); + } else { + types.push_back("String"); + } + } + } + + for (int i=0; iSetCellEditor(i, COL_T, new wxGridCellChoiceEditor(4, strChoices, false)); + + fieldGrid->SetCellValue(i, 0, col_names[i]); + fieldGrid->SetCellValue(i, COL_T, types[i]); + } + + + LOG_MSG("Exiting CsvFieldConfDlg::CsvFieldConfDlg(..)"); +} + + +void CsvFieldConfDlg::OnOkClick( wxCommandEvent& event ) +{ + bool success = false; + + wxString csvt; + + int n_rows = col_names.size(); + for (int r=0; r < n_rows; r++ ) { + wxString type = fieldGrid->GetCellValue(r, 1); + csvt << type; + if (r < n_rows-1) + csvt << ","; + } + + // write back to a CSVT file + wxString csvt_path = filepath + "t"; + wxTextFile file(csvt_path); + file.Open(); + file.Clear(); + + file.AddLine( csvt ); + + file.Write(); + file.Close(); + EndDialog(wxID_OK); +} + +void CsvFieldConfDlg::OnCancelClick( wxCommandEvent& event ) +{ + EndDialog(wxID_CANCEL); +} + diff --git a/DialogTools/CsvFieldConfDlg.h b/DialogTools/CsvFieldConfDlg.h new file mode 100644 index 000000000..532dc1898 --- /dev/null +++ b/DialogTools/CsvFieldConfDlg.h @@ -0,0 +1,56 @@ +/** + * GeoDa TM, Copyright (C) 2011-2015 by Luc Anselin - all rights reserved + * + * This file is part of GeoDa. + * + * GeoDa is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * GeoDa is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#ifndef __GEODA_CENTER_CSVFIELDCONF_DLG_H__ +#define __GEODA_CENTER_CSVFIELDCONF_DLG_H__ + + +#include +#include +#include +#include +#include +#include +#include +#include + + + + +class CsvFieldConfDlg: public wxDialog +{ +public: + CsvFieldConfDlg(wxWindow* parent, wxString filepath, + wxWindowID id = wxID_ANY, + const wxString& title = "GeoDa Csv Filed Configuration Dialog", + const wxPoint& pos = wxDefaultPosition, + const wxSize& size = wxSize(480,420)); + + +private: + wxString filepath; + wxGrid* fieldGrid; + + std::vector col_names; + + void OnOkClick( wxCommandEvent& event ); + void OnCancelClick( wxCommandEvent& event ); + +}; + +#endif From 33359d92f3ec0ce674e70f41a3dd05992a55ec9a Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 31 Aug 2016 14:20:26 -0500 Subject: [PATCH 11/15] #468 iterations -> sample size --- Explore/CorrelParamsDlg.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Explore/CorrelParamsDlg.cpp b/Explore/CorrelParamsDlg.cpp index 8799c5b05..8b004239e 100644 --- a/Explore/CorrelParamsDlg.cpp +++ b/Explore/CorrelParamsDlg.cpp @@ -138,7 +138,7 @@ help_btn(0), apply_btn(0) rand_samp_rad = new wxRadioButton(panel, XRCID("ID_RAND_SAMP_RAD"), "Random Sample", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTER_VERTICAL); rand_samp_rad->SetValue(correl_params.method != CorrelParams::ALL_PAIRS); Connect(XRCID("ID_RAND_SAMP_RAD"), wxEVT_RADIOBUTTON, wxCommandEventHandler(CorrelParamsFrame::OnRandSampRadioSelected)); - max_iter_txt = new wxStaticText(panel, XRCID("ID_MAX_ITER_TXT"), "Iterations:"); + max_iter_txt = new wxStaticText(panel, XRCID("ID_MAX_ITER_TXT"), "Sample Size:"); { wxString vs; vs << correl_params.max_iterations; @@ -682,13 +682,13 @@ wxString CorrelParamsFrame::GetHelpPageHtml() const s << "Random Sample for data sets with more than 10,000 observations."; s << "The Estimated Pairs gives the number of pairs of centers that will "; s << "be involved in the computation. This is comparable to the "; - s << "Iterations parameter in the Random Sample method."; + s << "sample size parameter in the Random Sample method."; s << "

"; s << "

Random Sample

"; s << "

"; s << "Pairs of observations are chosen at random up to the number "; - s << "of iterations specified. Random Sampling converges very quickly "; + s << "of sample size specified. Random Sampling converges very quickly "; s << "to similar values as in All Pairs, but had the advantage of "; s << "a constant running time. This is the only way to handle very "; s << "large data sets over the entire distance range."; From 8a3783c8b370ce62e025dd9c6b7925e66d490248 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 1 Sep 2016 11:03:39 -0500 Subject: [PATCH 12/15] ready for 1.8.12 --- DialogTools/ConnectDatasourceDlg.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/DialogTools/ConnectDatasourceDlg.cpp b/DialogTools/ConnectDatasourceDlg.cpp index 2ba3b853e..8e1e65cbe 100644 --- a/DialogTools/ConnectDatasourceDlg.cpp +++ b/DialogTools/ConnectDatasourceDlg.cpp @@ -202,11 +202,11 @@ void ConnectDatasourceDlg::OnOkClick( wxCommandEvent& event ) } // For csv file, if no csvt file, pop-up a field definition dialog and create a csvt file - if (ds_file_path.GetExt().Lower() == "csv") { - wxString csv_path = ds_file_path.GetFullPath(); - CsvFieldConfDlg csvDlg(this, csv_path); - csvDlg.ShowModal(); - } + //if (ds_file_path.GetExt().Lower() == "csv") { + // wxString csv_path = ds_file_path.GetFullPath(); + // CsvFieldConfDlg csvDlg(this, csv_path); + // csvDlg.ShowModal(); + //} CreateDataSource(); From 8daaf51514e4199d53daf741d152833c1359d69f Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 1 Sep 2016 11:04:11 -0500 Subject: [PATCH 13/15] update version number to 1.8.12 --- version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version.h b/version.h index b6e8d9ac8..df50b044b 100644 --- a/version.h +++ b/version.h @@ -1,11 +1,11 @@ namespace Gda { const int version_major = 1; const int version_minor = 8; - const int version_build = 11; - const int version_subbuild = 1; + const int version_build = 12; + const int version_subbuild = 0; const int version_year = 2016; - const int version_month = 8; - const int version_day = 29; + const int version_month = 9; + const int version_day = 1; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 246662c013ea4e910dcf8ba90f503237de109591 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 1 Sep 2016 14:45:00 -0600 Subject: [PATCH 14/15] Add csvFiledConf dialog to windows project --- BuildTools/windows/GeoDa.vcxproj | 2 ++ BuildTools/windows/GeoDa.vcxproj.filters | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/BuildTools/windows/GeoDa.vcxproj b/BuildTools/windows/GeoDa.vcxproj index 6e37531c5..d55f14972 100644 --- a/BuildTools/windows/GeoDa.vcxproj +++ b/BuildTools/windows/GeoDa.vcxproj @@ -205,6 +205,7 @@ + @@ -271,6 +272,7 @@ + diff --git a/BuildTools/windows/GeoDa.vcxproj.filters b/BuildTools/windows/GeoDa.vcxproj.filters index 86c17239f..f8c8be3c0 100644 --- a/BuildTools/windows/GeoDa.vcxproj.filters +++ b/BuildTools/windows/GeoDa.vcxproj.filters @@ -621,6 +621,9 @@ DialogTools + + DialogTools + @@ -1133,5 +1136,8 @@ DialogTools + + DialogTools + \ No newline at end of file From 13314bc70291ff54ce142a957dd2d84df1506041 Mon Sep 17 00:00:00 2001 From: xunli Date: Thu, 1 Sep 2016 20:07:23 -0500 Subject: [PATCH 15/15] remove ogr_SDE ogr_OCI dependents from Ubuntu --- BuildTools/ubuntu/build64.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BuildTools/ubuntu/build64.sh b/BuildTools/ubuntu/build64.sh index c205907dc..ed21d8aec 100755 --- a/BuildTools/ubuntu/build64.sh +++ b/BuildTools/ubuntu/build64.sh @@ -644,7 +644,7 @@ echo "%%%%%%%%%%%%%%%%%%%" mkdir ../../o $MAKER make app - cp plugins/x64/*.so build/plugins/ + #cp plugins/x64/*.so build/plugins/ cp ../CommonDistFiles/cache.sqlite build/ cp ../CommonDistFiles/geoda_prefs.sqlite build/ cp ../CommonDistFiles/geoda_prefs.json build/