From 57aa0ac90cda4a3b2aea49e639e9971b5074e93a Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 26 Oct 2016 15:02:40 -0500 Subject: [PATCH 1/9] #493 Weights bug related to arc distance --- DialogTools/CreatingWeightDlg.cpp | 2 +- version.h | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 88a7b9e1a..2acb375d8 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -310,7 +310,7 @@ void CreatingWeightDlg::OnCreateClick( wxCommandEvent& event ) 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 + //t_val /= GenGeomAlgs::one_mi_in_km; // convert km to mi } if (t_val > 0) { diff --git a/version.h b/version.h index df50b044b..ab893b942 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 8; const int version_build = 12; - const int version_subbuild = 0; + const int version_subbuild = 2; const int version_year = 2016; - const int version_month = 9; - const int version_day = 1; + const int version_month = 10; + const int version_day = 26; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 34fe99c918774c2d9840923c18c7ed0996eca446 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 26 Oct 2016 16:12:56 -0500 Subject: [PATCH 2/9] #495 propose fix centers not displaying in win --- Explore/MapNewView.cpp | 28 +++++++++++++++++----------- TemplateCanvas.cpp | 13 +++++++++---- 2 files changed, 26 insertions(+), 15 deletions(-) diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 6581ea2a1..c92bbc925 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -306,6 +306,7 @@ void MapCanvas::DrawLayerBase() { if (isDrawBasemap) { if (basemap != 0) { + basemap_bm->UseAlpha(); layerbase_valid = basemap->Draw(basemap_bm); #ifdef __linux__ // trigger to draw again, since it's drawing on ONE bitmap, @@ -368,11 +369,12 @@ void MapCanvas::DrawLayer0() void MapCanvas::resizeLayerBms(int width, int height) { deleteLayerBms(); - basemap_bm = new wxBitmap(width, height); + basemap_bm = new wxBitmap(width, height, 32); layer0_bm = new wxBitmap(width, height, 32); layer1_bm = new wxBitmap(width, height, 32); layer2_bm = new wxBitmap(width, height, 32); final_bm = new wxBitmap(width, height); + basemap_bm->UseAlpha(); layer0_bm->UseAlpha(); layer1_bm->UseAlpha(); layer2_bm->UseAlpha(); @@ -399,10 +401,16 @@ void MapCanvas::DrawLayer0() dc.SetBackground( *wxTRANSPARENT_BRUSH ); dc.Clear(); + wxGraphicsContext* gc = wxGraphicsContext::Create(dc); + if (!gc) + return; + BOOST_FOREACH( GdaShape* shp, background_shps ) { - shp->paintSelf(dc); + shp->paintSelf(gc); } + delete gc; + if (draw_sel_shps_by_z_val) { DrawSelectableShapesByZVal(dc); } else { @@ -452,10 +460,16 @@ void MapCanvas::DrawLayer2() wxMemoryDC dc(*layer2_bm); dc.SetBackground( *wxTRANSPARENT_BRUSH ); dc.Clear(); + + wxGraphicsContext* gc = wxGraphicsContext::Create(dc); + if (!gc) + return; BOOST_FOREACH( GdaShape* shp, foreground_shps ) { - shp->paintSelf(dc); + shp->paintSelf(gc); } + + delete gc; layer2_valid = true; } @@ -485,14 +499,6 @@ void MapCanvas::OnPaint(wxPaintEvent& event) // Draw the the selection region "the black selection box" if needed PaintSelectionOutline(paint_dc); - - // Draw optional control objects if needed, should be in memeory - // PaintControls(paint_dc); - - // The resize event will ruin the position of scroll bars, so we reset the - // position of scroll bars again. - //if (prev_scroll_pos_x > 0) SetScrollPos(wxHORIZONTAL, prev_scroll_pos_x); - //if (prev_scroll_pos_y > 0) SetScrollPos(wxVERTICAL, prev_scroll_pos_y); isRepaint = false; } diff --git a/TemplateCanvas.cpp b/TemplateCanvas.cpp index 51f0963f4..56423c62b 100644 --- a/TemplateCanvas.cpp +++ b/TemplateCanvas.cpp @@ -1121,19 +1121,23 @@ void TemplateCanvas::DrawSelectableShapes_gc(wxMemoryDC &dc) return; gc->SetPen(wxPen(selectable_outline_color)); gc->SetBrush(wxBrush(selectable_fill_color)); + int cc_ts = cat_data.curr_canvas_tm_step; int num_cats=cat_data.GetNumCategories(cc_ts); int w = layer0_bm->GetWidth(); int h = layer0_bm->GetHeight(); + if (selectable_shps_type == points) { int dirty_cnt = 0; gc->SetAntialiasMode(wxANTIALIAS_NONE); wxDouble r = GdaConst::my_point_click_radius; - if (w < 150 || h < 150) r *= 0.66; - if (selectable_shps.size() > 100 && (w < 80 || h < 80)) r = 0.2; + if (w < 150 || h < 150) + r *= 0.66; + if (selectable_shps.size() > 100 && (w < 80 || h < 80)) + r = 0.2; + GdaPoint* p; for (int cat=0; catSetPen(cat_data.GetCategoryPen(cc_ts, cat)); wxBrush br = cat_data.GetCategoryBrush(cc_ts, cat); - if (br.IsOk() ) gc->SetBrush(br); + if (br.IsOk() ) + gc->SetBrush(br); if (isDrawBasemap) { wxColour brushClr = cat_data.GetCategoryBrush(cc_ts, cat).GetColour(); From a8e3f7174ec66d45cddedb302d2c65334049f184 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 26 Oct 2016 16:32:52 -0500 Subject: [PATCH 3/9] #update #495 --- Explore/MapNewView.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index c92bbc925..5e6421f32 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -306,7 +306,7 @@ void MapCanvas::DrawLayerBase() { if (isDrawBasemap) { if (basemap != 0) { - basemap_bm->UseAlpha(); + //basemap_bm->UseAlpha(); layerbase_valid = basemap->Draw(basemap_bm); #ifdef __linux__ // trigger to draw again, since it's drawing on ONE bitmap, @@ -369,12 +369,12 @@ void MapCanvas::DrawLayer0() void MapCanvas::resizeLayerBms(int width, int height) { deleteLayerBms(); - basemap_bm = new wxBitmap(width, height, 32); + basemap_bm = new wxBitmap(width, height); layer0_bm = new wxBitmap(width, height, 32); layer1_bm = new wxBitmap(width, height, 32); layer2_bm = new wxBitmap(width, height, 32); final_bm = new wxBitmap(width, height); - basemap_bm->UseAlpha(); + //basemap_bm->UseAlpha(); layer0_bm->UseAlpha(); layer1_bm->UseAlpha(); layer2_bm->UseAlpha(); From ae492b8682de1c4d5092af86effa1e9234e52f3d Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 26 Oct 2016 15:51:35 -0600 Subject: [PATCH 4/9] update fix #495 add a fix for Save Image on windows issue --- Explore/Basemap.cpp | 8 ++++++-- Explore/MapNewView.cpp | 6 +++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Explore/Basemap.cpp b/Explore/Basemap.cpp index 9cbe1185d..8f2aecd67 100644 --- a/Explore/Basemap.cpp +++ b/Explore/Basemap.cpp @@ -655,7 +655,11 @@ bool Basemap::Draw(wxBitmap* buffer) { // when tiles pngs are ready, draw them on a buffer wxMemoryDC dc(*buffer); + dc.SetBackground( *wxTRANSPARENT_BRUSH ); dc.Clear(); + wxGraphicsContext* gc = wxGraphicsContext::Create(dc); + if (!gc) + return false; int x0 = startX; int x1 = endX; @@ -683,11 +687,11 @@ bool Basemap::Draw(wxBitmap* buffer) bmp.LoadFile(wxFilePath, wxBITMAP_TYPE_JPEG); } bool bmpOK = bmp.IsOk(); - if (bmpOK) dc.DrawBitmap(bmp, pos_x, pos_y, true); + if (bmpOK) gc->DrawBitmap(bmp, pos_x, pos_y, 256,256); //dc.DrawRectangle((i-startX) * 256 - offsetX, (j-startY) * 256 - offsetY, 256, 256); } } - + delete gc; isTileDrawn = true; return isTileReady; } diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 5e6421f32..c92bbc925 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -306,7 +306,7 @@ void MapCanvas::DrawLayerBase() { if (isDrawBasemap) { if (basemap != 0) { - //basemap_bm->UseAlpha(); + basemap_bm->UseAlpha(); layerbase_valid = basemap->Draw(basemap_bm); #ifdef __linux__ // trigger to draw again, since it's drawing on ONE bitmap, @@ -369,12 +369,12 @@ void MapCanvas::DrawLayer0() void MapCanvas::resizeLayerBms(int width, int height) { deleteLayerBms(); - basemap_bm = new wxBitmap(width, height); + basemap_bm = new wxBitmap(width, height, 32); layer0_bm = new wxBitmap(width, height, 32); layer1_bm = new wxBitmap(width, height, 32); layer2_bm = new wxBitmap(width, height, 32); final_bm = new wxBitmap(width, height); - //basemap_bm->UseAlpha(); + basemap_bm->UseAlpha(); layer0_bm->UseAlpha(); layer1_bm->UseAlpha(); layer2_bm->UseAlpha(); From e6543129b4df283d74c930e6997818d3fea3b6dd Mon Sep 17 00:00:00 2001 From: Xun Li Date: Wed, 26 Oct 2016 20:54:49 -0600 Subject: [PATCH 5/9] fix 2 bugs on windows 1. display centers 2. save as image with basemap boost performance for visualization on windows --- BuildTools/CommonDistFiles/GeoDa.ico | Bin 0 -> 353118 bytes BuildTools/windows/installer/32bit/GeoDa.iss | 59 +++++++++-- BuildTools/windows/installer/64bit/GeoDa.iss | 63 ++++++++++-- BuildTools/windows/run_geoda.bat | 10 ++ Explore/MapNewView.cpp | 102 +++++++++---------- Explore/MapNewView.h | 4 +- TemplateCanvas.cpp | 101 ++++++++++-------- 7 files changed, 231 insertions(+), 108 deletions(-) create mode 100644 BuildTools/CommonDistFiles/GeoDa.ico create mode 100644 BuildTools/windows/run_geoda.bat diff --git a/BuildTools/CommonDistFiles/GeoDa.ico b/BuildTools/CommonDistFiles/GeoDa.ico new file mode 100644 index 0000000000000000000000000000000000000000..179da6325e5640d8593755c202ad1b645ddba35f GIT binary patch literal 353118 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

Xte0piL9b4_CaL&Dg_k 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
@K((EG3VoP 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 literal 0 HcmV?d00001 diff --git a/BuildTools/windows/installer/32bit/GeoDa.iss b/BuildTools/windows/installer/32bit/GeoDa.iss index 73b40b0b6..ddca7b8af 100644 --- a/BuildTools/windows/installer/32bit/GeoDa.iss +++ b/BuildTools/windows/installer/32bit/GeoDa.iss @@ -21,11 +21,13 @@ OutputBaseFilename=geoda_setup ChangesAssociations=yes [dirs] +Name: "{app}"; Permissions: everyone-full; Check: InitializeSetup Name: "{app}\basemap_cache"; Permissions: everyone-full -Name: "{app}"; Permissions: everyone-full +Name: "{app}\Examples"; Permissions: everyone-full [Files] Source: "..\..\Release\GeoDa.exe"; DestDir: "{app}"; DestName: "GeoDa.exe" +Source: "..\..\..\CommonDistFiles\GeoDa.ico"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\copyright.txt"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\GPLv3.txt"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\cache.sqlite"; DestDir: "{app}" @@ -37,6 +39,7 @@ Source: "vcredist_x86.exe"; DestDir: "{app}" Source: "ogr_FileGDB.dll"; DestDir: "{app}" Source: "ogr_OCI.dll"; DestDir: "{app}" Source: "ogr_SDE.dll"; DestDir: "{app}" +Source: "..\..\run_geoda.bat"; DestDir: "{app}" Source: "..\..\Release\sqlite.dll"; DestDir: "{app}" Source: "..\..\temp\curl-7.30.0\builds\curlib\bin\libcurl.dll"; DestDir: "{app}" Source: "..\..\temp\expat-2.1.0\build\Release\expat.dll"; DestDir: "{app}" @@ -55,7 +58,7 @@ Source: "..\..\temp\boost_1_57_0\stage\lib\boost_chrono-vc100-mt-1_57.dll"; Dest Source: "..\..\temp\boost_1_57_0\stage\lib\boost_thread-vc100-mt-1_57.dll"; DestDir: "{app}" Source: "..\..\temp\boost_1_57_0\stage\lib\boost_system-vc100-mt-1_57.dll"; DestDir: "{app}" -Source: "..\..\..\..\SampleData\Examples\*"; DestDir: "{userdocs}\Examples"; Flags: recursesubdirs uninsneveruninstall +Source: "..\..\..\..\SampleData\Examples\*"; DestDir: "{app}\Examples"; Flags: recursesubdirs uninsneveruninstall Source: "..\..\temp\gdal\data\*"; DestDir: "{app}\data"; Flags: recursesubdirs @@ -63,16 +66,19 @@ Source: "..\..\temp\gdal\data\*"; DestDir: "{app}\data"; Flags: recursesubdirs ;Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme [Icons] -Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" Name: "{group}\Uninstall"; Filename: "{uninstallexe}" -Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" + [Registry] ; set PATH ; set GEODA_GDAL_DATA -Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_GDAL_DATA"; ValueData:"{pf}\GeoDa Software\data"; Flags: preservestringtype uninsdeletevalue +Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_GDAL_DATA"; ValueData:"{app}\data"; Flags: preservestringtype uninsdeletevalue ; set GEODA_OGR_DRIVER_PATH -Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_OGR_DRIVER_PATH"; ValueData:"{pf}\GeoDa Software"; Flags: preservestringtype uninsdeletevalue +Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_OGR_DRIVER_PATH"; ValueData:"{app}"; Flags: preservestringtype uninsdeletevalue Root: HKCR; Subkey: ".gda"; ValueType: string; ValueName: ""; ValueData: "GeoDaProjectFile"; Flags: uninsdeletevalue Root: HKCR; Subkey: "GeoDaProjectFile"; ValueType: string; ValueName: ""; ValueData: "GeoDa Project File"; Flags: uninsdeletekey @@ -109,5 +115,46 @@ begin Result := not RegKeyExists(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{F0C3E5D1-1ADE-321E-8167-68EF0DE699A5}'); end; +function GetUninstallString: string; +var + sUnInstPath: string; + sUnInstallString: String; +begin + Result := ''; + sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\GeoDa_is1'); //Your App GUID/ID + sUnInstallString := ''; + if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then + RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); + Result := sUnInstallString; +end; + +function IsUpgrade: Boolean; +begin + Result := (GetUninstallString() <> ''); +end; + +function InitializeSetup: Boolean; +var + V: Integer; + iResultCode: Integer; + sUnInstallString: string; +begin + Result := True; // in case when no previous version is found + if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\GeoDa_is1', 'UninstallString') then //Your App GUID/ID + begin + V := MsgBox(ExpandConstant('An old version of GeoDa was detected. Please uninstall it before continuing.'), mbInformation, MB_YESNO); //Custom Message if App installed + if V = IDYES then + begin + sUnInstallString := GetUninstallString(); + sUnInstallString := RemoveQuotes(sUnInstallString); + Exec(ExpandConstant(sUnInstallString), '', '', SW_SHOW, ewWaitUntilTerminated, iResultCode); + Result := True; //if you want to proceed after uninstall + //Exit; //if you want to quit after uninstall + end + else + Result := False; //when older version present and not uninstalled + end; +end; + [Run] Filename: {app}\vcredist_x86.exe; StatusMsg: Installing Visual Studio 2010 SP1 C++ CRT Libraries...; Check: VCRedistNeedsInstall diff --git a/BuildTools/windows/installer/64bit/GeoDa.iss b/BuildTools/windows/installer/64bit/GeoDa.iss index 2d8f0b3a2..417c82a5a 100644 --- a/BuildTools/windows/installer/64bit/GeoDa.iss +++ b/BuildTools/windows/installer/64bit/GeoDa.iss @@ -33,12 +33,15 @@ ArchitecturesInstallIn64BitMode=x64 ChangesAssociations=yes [dirs] +Name: "{app}"; Permissions: everyone-full; Check: InitializeSetup +Name: "{app}\Examples"; Permissions: everyone-full Name: "{app}\basemap_cache"; Permissions: everyone-full -Name: "{app}"; Permissions: everyone-full + [Files] Source: "..\..\Release\GeoDa.exe"; DestDir: "{app}"; DestName: "GeoDa.exe"; Check: IsX64 +Source: "..\..\..\CommonDistFiles\GeoDa.ico"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\copyright.txt"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\GPLv3.txt"; DestDir: "{app}" Source: "..\..\..\CommonDistFiles\cache.sqlite"; DestDir: "{app}" @@ -50,6 +53,7 @@ Source: "vcredist_x64.exe"; DestDir: "{app}" Source: "ogr_FileGDB.dll"; DestDir: "{app}" Source: "ogr_OCI.dll"; DestDir: "{app}" Source: "ogr_SDE.dll"; DestDir: "{app}" +Source: "..\..\run_geoda.bat"; DestDir: "{app}" Source: "..\..\Release\sqlite.dll"; DestDir: "{app}" Source: "..\..\temp\curl-7.46.0\builds\curlib\bin\libcurl.dll"; DestDir: "{app}" Source: "..\..\temp\expat-2.1.0\build\Release\expat.dll"; DestDir: "{app}" @@ -68,24 +72,25 @@ Source: "..\..\temp\boost_1_57_0\stage\lib\boost_chrono-vc100-mt-1_57.dll"; Dest Source: "..\..\temp\boost_1_57_0\stage\lib\boost_thread-vc100-mt-1_57.dll"; DestDir: "{app}" Source: "..\..\temp\boost_1_57_0\stage\lib\boost_system-vc100-mt-1_57.dll"; DestDir: "{app}" -Source: "..\..\..\..\SampleData\Examples\*"; DestDir: "{userdocs}\Examples"; Flags: recursesubdirs uninsneveruninstall - - +Source: "..\..\..\..\SampleData\Examples\*"; DestDir: "{app}\Examples"; Flags: recursesubdirs Source: "..\..\temp\gdal\data\*"; DestDir: "{app}\data"; Flags: recursesubdirs ;Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme [Icons] -Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" Name: "{group}\Uninstall"; Filename: "{uninstallexe}" -Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" + [Registry] ; set PATH ; set GEODA_GDAL_DATA -Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_GDAL_DATA"; ValueData:"{pf}\GeoDa Software\data"; Flags: preservestringtype uninsdeletevalue +Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_GDAL_DATA"; ValueData:"{app}\data"; Flags: preservestringtype uninsdeletevalue ; set GEODA_OGR_DRIVER_PATH -Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_OGR_DRIVER_PATH"; ValueData:"{pf}\GeoDa Software"; Flags: preservestringtype uninsdeletevalue +Root: HKCU; Subkey: "Environment"; ValueType:string; ValueName:"GEODA_OGR_DRIVER_PATH"; ValueData:"{app}"; Flags: preservestringtype uninsdeletevalue Root: HKCR; Subkey: ".gda"; ValueType: string; ValueName: ""; ValueData: "GeoDaProjectFile"; Flags: uninsdeletevalue Root: HKCR; Subkey: "GeoDaProjectFile"; ValueType: string; ValueName: ""; ValueData: "GeoDa Project File"; Flags: uninsdeletekey @@ -124,5 +129,47 @@ begin Result := not RegKeyExists(HKLM,'SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1D8E6291-B0D5-35EC-8441-6616F567A0F7}'); end; +function GetUninstallString: string; +var + sUnInstPath: string; + sUnInstallString: String; +begin + Result := ''; + sUnInstPath := ExpandConstant('Software\Microsoft\Windows\CurrentVersion\Uninstall\GeoDa_is1'); //Your App GUID/ID + sUnInstallString := ''; + if not RegQueryStringValue(HKLM, sUnInstPath, 'UninstallString', sUnInstallString) then + RegQueryStringValue(HKCU, sUnInstPath, 'UninstallString', sUnInstallString); + Result := sUnInstallString; +end; + +function IsUpgrade: Boolean; +begin + Result := (GetUninstallString() <> ''); +end; + +function InitializeSetup: Boolean; +var + V: Integer; + iResultCode: Integer; + sUnInstallString: string; +begin + Result := True; // in case when no previous version is found + if RegValueExists(HKEY_LOCAL_MACHINE,'Software\Microsoft\Windows\CurrentVersion\Uninstall\GeoDa_is1', 'UninstallString') then //Your App GUID/ID + begin + V := MsgBox(ExpandConstant('An old version of GeoDa was detected. Please uninstall it before continuing.'), mbInformation, MB_YESNO); //Custom Message if App installed + if V = IDYES then + begin + sUnInstallString := GetUninstallString(); + sUnInstallString := RemoveQuotes(sUnInstallString); + Exec(ExpandConstant(sUnInstallString), '', '', SW_SHOW, ewWaitUntilTerminated, iResultCode); + Result := True; //if you want to proceed after uninstall + //Exit; //if you want to quit after uninstall + end + else + Result := False; //when older version present and not uninstalled + end; +end; + [Run] Filename: {app}\vcredist_x64.exe; StatusMsg: Installing Visual Studio 2010 SP1 C++ CRT Libraries...; Check: VCRedistNeedsInstall + diff --git a/BuildTools/windows/run_geoda.bat b/BuildTools/windows/run_geoda.bat new file mode 100644 index 000000000..9e95f4480 --- /dev/null +++ b/BuildTools/windows/run_geoda.bat @@ -0,0 +1,10 @@ +@echo OFF +SET geodapath=%cd% +SET GEODA_GDAL_DATA="%geodapath%\data" +SET GEODA_OGR_DRIVER_PATH="%geodapath%" + +@echo %geodapath% +@echo %GEODA_GDAL_DATA% +@echo %GEODA_GDAL_DRIVER_PATH% + +start GeoDa.exe diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index c92bbc925..495d17297 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -110,8 +110,8 @@ void SliderDialog::OnSliderChange( wxScrollEvent & event ) IMPLEMENT_CLASS(MapCanvas, TemplateCanvas) BEGIN_EVENT_TABLE(MapCanvas, TemplateCanvas) -#ifdef __linux__ - // in Linux, using old paint function without transparency support +#ifndef __WXMAC__ + // in Linux, windows using old paint function without transparency support EVT_PAINT(TemplateCanvas::OnPaint) #else EVT_PAINT(MapCanvas::OnPaint) @@ -293,7 +293,7 @@ void MapCanvas::DrawLayers() DrawLayer1(); if (!layer2_valid) { - DrawLayer1(); + //DrawLayer1(); DrawLayer2(); } @@ -308,7 +308,7 @@ void MapCanvas::DrawLayerBase() if (basemap != 0) { basemap_bm->UseAlpha(); layerbase_valid = basemap->Draw(basemap_bm); -#ifdef __linux__ +#ifndef __WXMAC__ // trigger to draw again, since it's drawing on ONE bitmap, // not multilayer with transparency support layer0_valid = false; @@ -318,54 +318,8 @@ void MapCanvas::DrawLayerBase() } -#ifdef __linux__ -void MapCanvas::resizeLayerBms(int width, int height) -{ - deleteLayerBms(); - basemap_bm = new wxBitmap(width, height); - layer0_bm = new wxBitmap(width, height); - layer1_bm = new wxBitmap(width, height); - layer2_bm = new wxBitmap(width, height); - final_bm = new wxBitmap(width, height); - - layerbase_valid = false; - layer0_valid = false; - layer1_valid = false; - layer2_valid = false; -} - -void MapCanvas::DrawLayer0() -{ - //LOG_MSG("In TemplateCanvas::DrawLayer0"); - wxSize sz = GetVirtualSize(); - wxMemoryDC dc(*layer0_bm); - dc.SetPen(canvas_background_color); - dc.SetBrush(canvas_background_color); - dc.DrawRectangle(wxPoint(0,0), sz); - - if (isDrawBasemap) - dc.DrawBitmap(*basemap_bm, 0, 0); - - BOOST_FOREACH( GdaShape* shp, background_shps ) { - shp->paintSelf(dc); - } - if (draw_sel_shps_by_z_val) { - DrawSelectableShapesByZVal(dc); - } else { - DrawSelectableShapes(dc); - } - - layer0_valid = true; - layer1_valid = false; -} - -// in Linux, following 3 functions will be inherited from TemplateCanvas -//void MapCanvas::DrawLayer1() -//void MapCanvas::DrawLayer2() -//void MapCanvas::OnPaint(wxPaintEvent& event) - -#else +#ifdef __WXMAC__ void MapCanvas::resizeLayerBms(int width, int height) { deleteLayerBms(); @@ -504,6 +458,52 @@ void MapCanvas::OnPaint(wxPaintEvent& event) } event.Skip(); } +#else +void MapCanvas::resizeLayerBms(int width, int height) +{ + deleteLayerBms(); + basemap_bm = new wxBitmap(width, height); + layer0_bm = new wxBitmap(width, height); + layer1_bm = new wxBitmap(width, height); + layer2_bm = new wxBitmap(width, height); + final_bm = new wxBitmap(width, height); + + layerbase_valid = false; + layer0_valid = false; + layer1_valid = false; + layer2_valid = false; +} + +void MapCanvas::DrawLayer0() +{ + //LOG_MSG("In TemplateCanvas::DrawLayer0"); + wxSize sz = GetVirtualSize(); + wxMemoryDC dc(*layer0_bm); + + dc.SetPen(canvas_background_color); + dc.SetBrush(canvas_background_color); + dc.DrawRectangle(wxPoint(0,0), sz); + + if (isDrawBasemap) + dc.DrawBitmap(*basemap_bm, 0, 0); + + BOOST_FOREACH( GdaShape* shp, background_shps ) { + shp->paintSelf(dc); + } + if (draw_sel_shps_by_z_val) { + DrawSelectableShapesByZVal(dc); + } else { + DrawSelectableShapes(dc); + } + + layer0_valid = true; + layer1_valid = false; +} + +// in Linux, following 3 functions will be inherited from TemplateCanvas +//void MapCanvas::DrawLayer1() +//void MapCanvas::DrawLayer2() +//void MapCanvas::OnPaint(wxPaintEvent& event) #endif diff --git a/Explore/MapNewView.h b/Explore/MapNewView.h index 6b9a21906..71f59f683 100644 --- a/Explore/MapNewView.h +++ b/Explore/MapNewView.h @@ -119,8 +119,8 @@ class MapCanvas : public TemplateCanvas, public CatClassifStateObserver bool DrawBasemap(bool flag, int map_type); virtual void DrawLayerBase(); virtual void DrawLayers(); -#ifdef __linux__ - // in linux, use old style drawing without transparency support +#ifndef __WXMAC__ + // in linux, windows use old style drawing without transparency support // the commented out functions are inherited from TemplateCanvas class // TODO will be replace by wxImage drawing code virtual void resizeLayerBms(int width, int height); diff --git a/TemplateCanvas.cpp b/TemplateCanvas.cpp index 56423c62b..fedd23016 100644 --- a/TemplateCanvas.cpp +++ b/TemplateCanvas.cpp @@ -1102,7 +1102,7 @@ void TemplateCanvas::DrawSelectableShapes(wxMemoryDC &dc) #ifdef __WXMAC__ DrawSelectableShapes_gc(dc); #else - DrawSelectableShapes_gc(dc); + DrawSelectableShapes_dc(dc); #endif } else { for (int i=0, iend=selectable_shps.size(); i 100 && (w < 80 || h < 80)) r = 0.2; + int bnd = w*h; + std::vector dirty(bnd, false); + GdaPoint* p; for (int cat=0; catisNull()) continue; - path.AddCircle(p->center.x, p->center.y, r); - + //path.AddCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + path.AddCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } gc->StrokePath(path); @@ -1335,7 +1342,8 @@ void TemplateCanvas::DrawSelectableShapes_gen_dc(wxDC &dc) int w = layer0_bm->GetWidth(); int h = layer0_bm->GetHeight(); if (selectable_shps_type == points) { - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); int dirty_cnt = 0; dc.SetBrush(*wxTRANSPARENT_BRUSH); wxDouble r = GdaConst::my_point_click_radius; @@ -1349,11 +1357,12 @@ void TemplateCanvas::DrawSelectableShapes_gen_dc(wxDC &dc) for (int i=0, iend=ids.size(); iisNull()) continue; - dc.DrawCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //dc.DrawCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //dc.DrawCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + dc.DrawCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } } } else if (selectable_shps_type == polygons) { @@ -1431,7 +1440,7 @@ void TemplateCanvas::DrawHighlightedShapes(wxMemoryDC &dc) #ifdef __WXMAC__ DrawHighlightedShapes_gc(dc); #else - DrawHighlightedShapes_gc(dc); + DrawHighlightedShapes_dc(dc); #endif return; } @@ -1460,7 +1469,8 @@ void TemplateCanvas::DrawHighlightedShapes_gc(wxMemoryDC &dc) int h = layer0_bm->GetHeight(); if (selectable_shps_type == points) { - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); GdaPoint* p; gc->SetAntialiasMode(wxANTIALIAS_NONE); gc->SetPen(wxPen(highlight_color)); @@ -1472,11 +1482,12 @@ void TemplateCanvas::DrawHighlightedShapes_gc(wxMemoryDC &dc) if (hs[i]) { p = (GdaPoint*) selectable_shps[i]; if (p->isNull()) continue; - path.AddCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //path.AddCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //path.AddCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + path.AddCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } } gc->StrokePath(path); @@ -1601,7 +1612,8 @@ void TemplateCanvas::DrawHighlightedShapes_gen_dc(wxDC &dc, int h = layer0_bm->GetHeight(); if (selectable_shps_type == points) { - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); GdaPoint* p; dc.SetPen(hc_pen); dc.SetBrush(*wxTRANSPARENT_BRUSH); @@ -1612,11 +1624,12 @@ void TemplateCanvas::DrawHighlightedShapes_gen_dc(wxDC &dc, if (hs[i]) { p = (GdaPoint*) selectable_shps[i]; if (p->isNull()) continue; - dc.DrawCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //dc.DrawCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //c.DrawCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + dc.DrawCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } } } else if (selectable_shps_type == polygons) { @@ -1676,7 +1689,7 @@ void TemplateCanvas::DrawNewSelShapes(wxMemoryDC &dc) #ifdef __WXMAC__ DrawNewSelShapes_gc(dc); #else - DrawNewSelShapes_gc(dc); + DrawNewSelShapes_dc(dc); #endif return; } @@ -1709,7 +1722,8 @@ void TemplateCanvas::DrawNewSelShapes_gc(wxMemoryDC &dc) std::vector& nh = GetNewlySelList(); if (selectable_shps_type == points) { - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); GdaPoint* p; gc->SetAntialiasMode(wxANTIALIAS_NONE); gc->SetPen(hc_pen); @@ -1720,11 +1734,12 @@ void TemplateCanvas::DrawNewSelShapes_gc(wxMemoryDC &dc) for (int i=0; iisNull()) continue; - path.AddCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //path.AddCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //path.AddCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + path.AddCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } gc->StrokePath(path); } else if (selectable_shps_type == polygons) { @@ -1837,7 +1852,8 @@ void TemplateCanvas::DrawNewSelShapes_dc(wxMemoryDC &dc) std::vector& nh = GetNewlySelList(); if (selectable_shps_type == points) { - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); dc.SetPen(hc_pen); dc.SetBrush(*wxTRANSPARENT_BRUSH); GdaPoint* p; @@ -1847,11 +1863,12 @@ void TemplateCanvas::DrawNewSelShapes_dc(wxMemoryDC &dc) for (int i=0; iisNull()) continue; - dc.DrawCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //dc.DrawCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //dc.DrawCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd && !dirty[bnd_idx]) { + dc.DrawCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } } else if (selectable_shps_type == polygons) { GdaPolygon* p; @@ -2100,7 +2117,8 @@ void TemplateCanvas::EraseNewUnSelShapes_dc(wxMemoryDC &dc) if (selectable_shps_type == points) { dc.SetBrush(*wxTRANSPARENT_BRUSH); - //std::vector dirty(w*h, false); + int bnd = w*h; + std::vector dirty(bnd, false); GdaPoint* p; wxDouble r = GdaConst::my_point_click_radius; if (w < 150 || h < 150) r *= 0.66; @@ -2110,11 +2128,12 @@ void TemplateCanvas::EraseNewUnSelShapes_dc(wxMemoryDC &dc) for (int i=0, iend=total_in_cat[cat]; iisNull()) continue; - dc.DrawCircle(p->center.x, p->center.y, r); - //if (!dirty[p->center.x + p->center.y*w]) { - //dc.DrawCircle(p->center.x, p->center.y, r); - //dirty[p->center.x + p->center.y*w] = true; - //} + //dc.DrawCircle(p->center.x, p->center.y, r); + int bnd_idx = p->center.x + p->center.y*w; + if (bnd_idx >= 0 && bnd_idx < bnd&& !dirty[bnd_idx]) { + dc.DrawCircle(p->center.x, p->center.y, r); + dirty[bnd_idx] = true; + } } } } else if (selectable_shps_type == polygons) { From 0d39e0f474c744cbd0f4e7fff1ba5881ce3bde62 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 8 Nov 2016 11:57:42 -0600 Subject: [PATCH 6/9] #516 problem with LM Error test --- ShapeOperations/GalWeight.cpp | 1 + ShapeOperations/GalWeight.h | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/ShapeOperations/GalWeight.cpp b/ShapeOperations/GalWeight.cpp index 76e0dc15d..8ad472550 100644 --- a/ShapeOperations/GalWeight.cpp +++ b/ShapeOperations/GalWeight.cpp @@ -122,6 +122,7 @@ void GalElement::SetNbrs(const GalElement& gal) nbr = gal.GetNbrs(); nbrWeight = gal.GetNbrWeights(); + nbrLookup = gal.nbrLookup; } const std::vector & GalElement::GetNbrs() const diff --git a/ShapeOperations/GalWeight.h b/ShapeOperations/GalWeight.h index 0b303214a..f6556194a 100644 --- a/ShapeOperations/GalWeight.h +++ b/ShapeOperations/GalWeight.h @@ -47,8 +47,9 @@ class GalElement { double GetRW(int idx); bool Check(long nbrIdx); -private: std::map nbrLookup; // nbr_id, idx_in_nbrWeight + +private: std::vector nbr; std::vector nbrWeight; std::vector nbrAvgW; From c59982182c6b167002bce8f6a955c990f28b89e8 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 8 Nov 2016 14:00:43 -0600 Subject: [PATCH 7/9] update #516 --- DialogTools/CreatingWeightDlg.cpp | 1 + Regression/smile2.cpp | 66 ++++++++++++++++--------------- ShapeOperations/GalWeight.cpp | 11 ++++-- ShapeOperations/GalWeight.h | 5 ++- 4 files changed, 45 insertions(+), 38 deletions(-) diff --git a/DialogTools/CreatingWeightDlg.cpp b/DialogTools/CreatingWeightDlg.cpp index 2acb375d8..b8c8cd847 100644 --- a/DialogTools/CreatingWeightDlg.cpp +++ b/DialogTools/CreatingWeightDlg.cpp @@ -1219,6 +1219,7 @@ bool CreatingWeightDlg::WriteWeightFile(GalElement *gal, GwtElement *gwt, } //GdaFrame::GetGdaFrame()->ShowConnectivityMapView(uid); } + delete w; } else { success = false; } diff --git a/Regression/smile2.cpp b/Regression/smile2.cpp index 76df74fb7..2eda26a6a 100644 --- a/Regression/smile2.cpp +++ b/Regression/smile2.cpp @@ -48,7 +48,7 @@ void Compute_RSLmError(GalElement* g, double *resid, int dim, double* rst, - const std::vector< std::set >& g_lookup); + double t); void Compute_RSLmErrorRobust(GalElement* g, double** cov, @@ -59,7 +59,7 @@ void Compute_RSLmErrorRobust(GalElement* g, int dim, int expl, double* rst, - const std::vector< std::set >& g_lookup); + double t); void Compute_RSLmLag(GalElement* g, double** cov, @@ -70,7 +70,7 @@ void Compute_RSLmLag(GalElement* g, int dim, int expl, double* rst, - const std::vector< std::set >& g_lookup); + double t); void Compute_RSLmLagRobust(GalElement* g, double** cov, @@ -81,7 +81,7 @@ void Compute_RSLmLagRobust(GalElement* g, int dim, int expl, double* rst, - const std::vector< std::set >& g_lookup); + double t); void Compute_RSLmSarma(GalElement* g, double** cov, @@ -92,7 +92,7 @@ void Compute_RSLmSarma(GalElement* g, int dim, int expl, double* rst, - const std::vector< std::set >& g_lookup); + double t); bool ordinaryLS(DenseVector &y, @@ -129,10 +129,7 @@ void MakeFastLookupMat(GalElement *g, int dim, } } -// Note: it is expected that input g_lookup was initialized as follows: -// MakeFastLookupMat(g, dim, g_lookup); -double T(GalElement *g, int dim, - const std::vector< std::set >& g_lookup) +double T(GalElement *g, int dim) { // tr(W'W+WW) // = tr(W'W) + tr(WW) @@ -140,7 +137,8 @@ double T(GalElement *g, int dim, using namespace std; double sum = 0; - + + /* int i=0, j=0; for (i = 0; i < dim; ++i) { for (j = 0; j < dim; ++j) { @@ -157,7 +155,17 @@ double T(GalElement *g, int dim, sum += g[j].GetRW(i) * g[j].GetRW(i); } } + */ + for (int i = 0; i < dim; ++i) { + for (int j = 0; j < dim; ++j) { + double w_ij = g[i].GetRW(j); + double w_ji = g[j].GetRW(i); + sum += w_ij * w_ji; + sum += w_ji * w_ji; + + } + } /* // below is also incorrect when handling knn weights matrix int cnt = 0, cp = 0; @@ -209,7 +217,7 @@ void Compute_RSLmLag(GalElement* g, int dim, int expl, double *rst, - const std::vector< std::set >& g_lookup) + double t) // t = T(g, dim, g_lookup) { double *Y = y.getThis(); double const ee = norm(resid, dim); @@ -235,7 +243,7 @@ void Compute_RSLmLag(GalElement* g, z.squareTimesColumn( z2, cov ); // z2 = (X'X)^(-1)X'WXb const double xMx = z.product(z2); // (WXb)'X(X'X)^(-1)X'WXb // lag.norm : (WXb)'(WXb) - double v = (lag.norm() - xMx + T(g, dim, g_lookup) * sigma2) / sigma2; + double v = (lag.norm() - xMx + t * sigma2) / sigma2; RS /= v; double const RS_stat = gammp( 0.5, RS * 0.5); @@ -257,7 +265,7 @@ void Compute_RSLmLagRobust(GalElement* g, int dim, int expl, double *rst, - const std::vector< std::set >& g_lookup) + double T21) // T21 = T(g, dim, g_lookup) { double *Y = y.getThis(); double const ee = norm(resid, dim); @@ -292,7 +300,6 @@ void Compute_RSLmLagRobust(GalElement* g, // z.product(z2) : (WXb)'(X(X'X)^(-1)X')(WXb) const double T11 = Wy.norm() - z.product(z2); const double T1 = T11 / sigma2; - const double T21 = T(g, dim, g_lookup); const double T2 = 1.0 / (T1 + T21); RS /= (1.0 / T2 - T21); @@ -486,11 +493,10 @@ double Compute_MoranZ(GalElement* g, // // Performs spatial error test specification: computes RS statistic -// +// t = tr[(W'+W)*W] void Compute_RSLmError(GalElement* g, double *resid, - int dim, double *rst, - const std::vector< std::set >& g_lookup) + int dim, double *rst, double t) { double const ee = norm(resid, dim); double const sigma2 = ee / (dim); @@ -505,7 +511,6 @@ void Compute_RSLmError(GalElement* g, double RS = geoda_sqr(re.product( lag ) / sigma2); // [e'We/sigma2]^2 - double t = T(g, dim, g_lookup); // tr[(W'+W)*W] RS /= t; double const RS_stat = gammp( 0.5, RS * 0.5); @@ -523,7 +528,7 @@ void Compute_RSLmErrorRobust(GalElement* g, int dim, int expl, double *rst, - const std::vector< std::set >& g_lookup) + double T21) //T21 = T(g, dim, g_lookup) tr[(W'+W)*W] { double *Y = y.getThis(); double const ee = norm(resid, dim); @@ -556,7 +561,7 @@ void Compute_RSLmErrorRobust(GalElement* g, // z.product(z2) : (WXb)'(X(X'X)^(-1)X')(WXb) const double T11 = Wy.norm() - z.product(z2); const double T1 = T11 / sigma2; - const double T21 = T(g, dim, g_lookup); + const double T2 = 1.0 / (T1 + T21); const double RS = geoda_sqr(RS2 - (RS1 * T2 * T21)) / (T21-(T21*T21*T2)); @@ -576,7 +581,7 @@ void Compute_RSLmSarma(GalElement* g, int dim, int expl, double *rst, - const std::vector< std::set >& g_lookup) + double T21) { double *Y = y.getThis(); double const ee = norm(resid, dim); @@ -609,7 +614,7 @@ void Compute_RSLmSarma(GalElement* g, // z.product(z2) : (WXb)'(X(X'X)^(-1)X')(WXb) const double T11 = Wy.norm() - z.product(z2); const double T1 = T11 / sigma2; - const double T21 = T(g, dim, g_lookup); + const double T2 = 1.0 / (T1 + T21); const double RS = (geoda_sqr(RS1 - RS2)/ (1.0/T2 - T21)) + (RS2*RS2/T21); @@ -738,38 +743,35 @@ bool classicalRegression(GalElement *g, // diagnostics for spatial dependence if (g != NULL) { - std::vector< std::set > g_lookup; - MakeFastLookupMat(g, dim, g_lookup); - double *rst = new double[2]; + + double t = T(g, dim); // tr[(W'+W)*W] - Compute_RSLmError(g, resid, dim, rst, g_lookup); + Compute_RSLmError(g, resid, dim, rst, t); dr->SetLmError(0, 1.0); dr->SetLmError(1, rst[0]); dr->SetLmError(2, rst[1]); - Compute_RSLmErrorRobust(g, cov, y, x, ols, resid, dim, expl, rst, - g_lookup); + Compute_RSLmErrorRobust(g, cov, y, x, ols, resid, dim, expl, rst, t); dr->SetLmErrRobust(0, 1.0); dr->SetLmErrRobust(1, rst[0]); dr->SetLmErrRobust(2, rst[1]); - Compute_RSLmLag(g, cov, y, x, ols, resid, dim, expl, rst, g_lookup); + Compute_RSLmLag(g, cov, y, x, ols, resid, dim, expl, rst, t); dr->SetLmLag(0, 1.0); dr->SetLmLag(1, rst[0]); dr->SetLmLag(2, rst[1]); - Compute_RSLmLagRobust(g, cov, y, x, ols, resid, dim, expl, rst, - g_lookup); + Compute_RSLmLagRobust(g, cov, y, x, ols, resid, dim, expl, rst, t); dr->SetLmLagRobust(0, 1.0); dr->SetLmLagRobust(1, rst[0]); dr->SetLmLagRobust(2, rst[1]); - Compute_RSLmSarma(g, cov, y, x, ols, resid, dim, expl, rst, g_lookup); + Compute_RSLmSarma(g, cov, y, x, ols, resid, dim, expl, rst, t); dr->SetLmSarma(0, 2.0); dr->SetLmSarma(1, rst[0]); dr->SetLmSarma(2, rst[1]); diff --git a/ShapeOperations/GalWeight.cpp b/ShapeOperations/GalWeight.cpp index 8ad472550..c2e4ea5ff 100644 --- a/ShapeOperations/GalWeight.cpp +++ b/ShapeOperations/GalWeight.cpp @@ -36,6 +36,7 @@ GalElement::GalElement() { + is_nbrAvgW_empty = true; } bool GalElement::Check(long nbrIdx) @@ -48,7 +49,7 @@ bool GalElement::Check(long nbrIdx) // return row standardized weights value double GalElement::GetRW(int idx) { - if (nbrAvgW.empty()) { + if (is_nbrAvgW_empty) { size_t sz = nbr.size(); nbrAvgW.resize(sz); double sumW = 0.0; @@ -59,11 +60,12 @@ double GalElement::GetRW(int idx) for (size_t i=0; i & GalElement::GetNbrs() const diff --git a/ShapeOperations/GalWeight.h b/ShapeOperations/GalWeight.h index f6556194a..34a93114f 100644 --- a/ShapeOperations/GalWeight.h +++ b/ShapeOperations/GalWeight.h @@ -46,13 +46,14 @@ class GalElement { double SpatialLag(const std::vector& x, const int* perm) const; double GetRW(int idx); bool Check(long nbrIdx); - + + bool is_nbrAvgW_empty; + std::vector nbrAvgW; std::map nbrLookup; // nbr_id, idx_in_nbrWeight private: std::vector nbr; std::vector nbrWeight; - std::vector nbrAvgW; }; class GalWeight : public GeoDaWeight { From d2a39625c7d214e7697de56ab5787995c3cf74b8 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 8 Nov 2016 14:01:41 -0600 Subject: [PATCH 8/9] update version 1.8.14 --- version.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/version.h b/version.h index ab893b942..fa9f3bd51 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 = 12; - const int version_subbuild = 2; + const int version_build = 14; + const int version_subbuild = 0; const int version_year = 2016; - const int version_month = 10; - const int version_day = 26; + const int version_month = 11; + const int version_day = 8; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 40a9a753c5600471c8c97a09420f98df70980990 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 8 Nov 2016 14:40:59 -0600 Subject: [PATCH 9/9] update windows build scripts for auto-update will ignore run_geoda.bat --- BuildTools/windows/installer/32bit/GeoDa.iss | 8 ++++---- BuildTools/windows/installer/64bit/GeoDa.iss | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/BuildTools/windows/installer/32bit/GeoDa.iss b/BuildTools/windows/installer/32bit/GeoDa.iss index ddca7b8af..9ce83b733 100644 --- a/BuildTools/windows/installer/32bit/GeoDa.iss +++ b/BuildTools/windows/installer/32bit/GeoDa.iss @@ -66,11 +66,11 @@ Source: "..\..\temp\gdal\data\*"; DestDir: "{app}\data"; Flags: recursesubdirs ;Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme [Icons] -;Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" -Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" +Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" Name: "{group}\Uninstall"; Filename: "{uninstallexe}" -;Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" -Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" +Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" [Registry] diff --git a/BuildTools/windows/installer/64bit/GeoDa.iss b/BuildTools/windows/installer/64bit/GeoDa.iss index 417c82a5a..dce8f8309 100644 --- a/BuildTools/windows/installer/64bit/GeoDa.iss +++ b/BuildTools/windows/installer/64bit/GeoDa.iss @@ -78,11 +78,11 @@ Source: "..\..\temp\gdal\data\*"; DestDir: "{app}\data"; Flags: recursesubdirs ;Source: "Readme.txt"; DestDir: "{app}"; Flags: isreadme [Icons] -;Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" -Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" +Name: "{group}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{group}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" Name: "{group}\Uninstall"; Filename: "{uninstallexe}" -;Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" -Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" +Name: "{commondesktop}\GeoDa"; Filename: "{app}\GeoDa.exe" +;Name: "{commondesktop}\GeoDa"; Filename: "{app}\run_geoda.bat"; IconFilename: "{app}\GeoDa.ico" [Registry]