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/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
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/
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
diff --git a/DialogTools/ConnectDatasourceDlg.cpp b/DialogTools/ConnectDatasourceDlg.cpp
index 5ed67d39b..8e1e65cbe 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/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp
index 3cea4596e..88a7b9e1a 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();
@@ -296,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 ";
@@ -327,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;
@@ -653,8 +667,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 +680,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;
@@ -914,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;
@@ -1055,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/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
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/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.";
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/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
#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;
@@ -1320,6 +1332,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/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/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
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 6dd8ff212..59c40782e 100644
--- a/ShapeOperations/WeightUtils.cpp
+++ b/ShapeOperations/WeightUtils.cpp
@@ -56,7 +56,34 @@ 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.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) {
key_field = "";
@@ -99,7 +126,33 @@ 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.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;
@@ -346,7 +399,32 @@ 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.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;
@@ -576,7 +654,32 @@ 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.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;
diff --git a/ShapeOperations/WeightsManPtree.cpp b/ShapeOperations/WeightsManPtree.cpp
index 8eaf0f330..efecdc991 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();
@@ -269,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");
@@ -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/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;
diff --git a/VarCalc/WeightsMetaInfo.cpp b/VarCalc/WeightsMetaInfo.cpp
index daef9b71e..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,12 +70,14 @@ 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,
DistanceMetricEnum dist_metric_,
DistanceUnitsEnum dist_units_,
+ wxString dist_units_str_,
DistanceValuesEnum dist_values_,
double threshold_val_,
wxString dist_var1_, long dist_tm1_,
@@ -86,6 +89,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 +105,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 +117,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 +230,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
diff --git a/version.h b/version.h
index eee789ed4..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 = 10;
+ const int version_build = 12;
const int version_subbuild = 0;
const int version_year = 2016;
- const int version_month = 7;
- const int version_day = 14;
+ 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
}