From f7174ce7532baf91bbd6d5e60ad042c0088a0fba Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 27 Sep 2018 10:59:19 -0700 Subject: [PATCH 1/9] update windows build --- BuildTools/windows/installer/32bit/GeoDa.iss | 16 ++++++++++------ BuildTools/windows/installer/64bit/GeoDa.iss | 2 +- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/BuildTools/windows/installer/32bit/GeoDa.iss b/BuildTools/windows/installer/32bit/GeoDa.iss index 6b80dbb28..f2076383f 100644 --- a/BuildTools/windows/installer/32bit/GeoDa.iss +++ b/BuildTools/windows/installer/32bit/GeoDa.iss @@ -20,10 +20,17 @@ OutputBaseFilename=geoda_setup ChangesAssociations=yes +ShowLanguageDialog=yes + +[Languages] +Name: "en"; MessagesFile: "compiler:Default.isl" +Name: "zh"; MessagesFile: "compiler:Languages\ChineseSimplified.isl" + [dirs] Name: "{app}"; Permissions: everyone-full; Check: InitializeSetup -Name: "{app}\basemap_cache"; Permissions: everyone-full -Name: "{app}\Examples"; Permissions: everyone-full +Name: "{app}\Examples"; Permissions: everyone-full +Name: "{app}\basemap_cache"; Permissions: everyone-full +Name: "{app}\lang"; Permissions: everyone-full [Files] Source: "..\..\Release\GeoDa.exe"; DestDir: "{app}"; DestName: "GeoDa.exe" @@ -61,9 +68,7 @@ Source: "..\..\temp\boost_1_57_0\stage\lib\boost_system-vc100-mt-1_57.dll"; Dest Source: "..\..\..\..\Algorithms\lisa_kernel.cl"; DestDir: "{app}" Source: "..\..\..\..\internationalization\lang\*"; DestDir: "{app}\lang"; Flags: recursesubdirs -Source: "..\..\..\..\SampleData\Examples\*"; DestDir: "{app}\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 @@ -75,7 +80,6 @@ Name: "{group}\Uninstall"; Filename: "{uninstallexe}" 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 diff --git a/BuildTools/windows/installer/64bit/GeoDa.iss b/BuildTools/windows/installer/64bit/GeoDa.iss index d85bcf50a..7de8d1ca1 100644 --- a/BuildTools/windows/installer/64bit/GeoDa.iss +++ b/BuildTools/windows/installer/64bit/GeoDa.iss @@ -64,11 +64,11 @@ 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}" +Source: "..\..\temp\gdal\gdal_geoda20.dll"; DestDir: "{app}" Source: "..\..\temp\libspatialite-4.0.0\spatialite.dll"; DestDir: "{app}" Source: "..\..\temp\geos-3.3.8\src\geos_c.dll"; DestDir: "{app}" Source: "..\..\temp\freexl-1.0.0e\freexl.dll"; DestDir: "{app}" Source: "..\..\temp\proj-4.8.0\src\proj.dll"; DestDir: "{app}" -Source: "..\..\temp\gdal\gdal_geoda20.dll"; DestDir: "{app}" Source: "..\..\temp\pgsql\lib\libpq.dll"; DestDir: "{app}" Source: "..\..\temp\pgsql\bin\ssleay32.dll"; DestDir: "{app}" Source: "..\..\temp\pgsql\bin\libintl-8.dll"; DestDir: "{app}" From 207ffb6ef808b8c92930e993459551e6d3de67ae Mon Sep 17 00:00:00 2001 From: Xun Li Date: Thu, 27 Sep 2018 13:16:29 -0700 Subject: [PATCH 2/9] update po files for international version --- Explore/MapLayerTree.cpp | 2 +- GeneralWxUtils.cpp | 16 +- internationalization/lang/es/GeoDa.mo | Bin 104715 -> 105000 bytes internationalization/lang/zh_CN/GeoDa.mo | Bin 112610 -> 113018 bytes internationalization/pofiles/es.po | 293 ++++++++++++++++------- internationalization/pofiles/zh_CN.po | 274 ++++++++++++++------- 6 files changed, 405 insertions(+), 180 deletions(-) diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index cd95b4806..0d43b333a 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -37,7 +37,7 @@ SetAssociationDlg::SetAssociationDlg(wxWindow* parent, AssociateLayerInt* ml,vec layer_list.push_back(new wxChoice(this, XRCID(layer_id), wxDefaultPosition, wxSize(100,-1))); field_list.push_back(new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(100,-1))); my_field_list.push_back(new wxChoice(this, wxID_ANY, wxDefaultPosition, wxSize(100,-1))); - conn_list.push_back(new wxCheckBox(this, wxID_ANY, "Show Connect line")); + conn_list.push_back(new wxCheckBox(this, wxID_ANY, _("Show connect line"))); layer_list[i]->Bind(wxEVT_CHOICE, &SetAssociationDlg::OnLayerSelect, this); } diff --git a/GeneralWxUtils.cpp b/GeneralWxUtils.cpp index 67eae8122..16ca14022 100644 --- a/GeneralWxUtils.cpp +++ b/GeneralWxUtils.cpp @@ -42,17 +42,17 @@ void SimpleReportTextCtrl::OnContextMenu(wxContextMenuEvent& event) { wxMenu* menu = new wxMenu; // Some standard items - menu->Append(XRCID("SAVE_SIMPLE_REPORT"), _("&Save")); + menu->Append(XRCID("SAVE_SIMPLE_REPORT"), _("Save")); menu->AppendSeparator(); - menu->Append(wxID_UNDO, _("&Undo")); - menu->Append(wxID_REDO, _("&Redo")); + menu->Append(wxID_UNDO, _("Undo")); + menu->Append(wxID_REDO, _("Redo")); menu->AppendSeparator(); - menu->Append(wxID_CUT, _("Cu&t")); - menu->Append(wxID_COPY, _("&Copy")); - menu->Append(wxID_PASTE, _("&Paste")); - menu->Append(wxID_CLEAR, _("&Delete")); + menu->Append(wxID_CUT, _("Cut")); + menu->Append(wxID_COPY, _("Copy")); + menu->Append(wxID_PASTE, _("Paste")); + menu->Append(wxID_CLEAR, _("Delete")); menu->AppendSeparator(); - menu->Append(wxID_SELECTALL, _("Select &All")); + menu->Append(wxID_SELECTALL, _("Select All")); // Add any custom items here Connect(XRCID("SAVE_SIMPLE_REPORT"), wxEVT_COMMAND_MENU_SELECTED, wxCommandEventHandler(SimpleReportTextCtrl::OnSaveClick)); diff --git a/internationalization/lang/es/GeoDa.mo b/internationalization/lang/es/GeoDa.mo index f827013943cddf3607d41cbc28d02242c78080e0..99d1f0250bf6e06a26162827acfebf282ba2928b 100644 GIT binary patch delta 28108 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 F{{blr;+y~g delta 27806 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 diff --git a/internationalization/lang/zh_CN/GeoDa.mo b/internationalization/lang/zh_CN/GeoDa.mo index b479cd94897d5ff562db97eac179b3e9086d192f..726c23e203cace6a0a8ac229c60d585ae377ae35 100644 GIT binary patch delta 31365 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" msgstr ">" @@ -3836,9 +3875,6 @@ msgstr "项目文件包含不直接存储在数据源中的额外信息, 例如 msgid "Open Datasource:" msgstr "打开数据源:" -msgid "&Tools" -msgstr "工具" - msgid "Tools" msgstr "工具" @@ -3877,9 +3913,6 @@ msgstr "" msgid "Save Categories to Table" msgstr "将自定义分类保存到表中" -msgid "Tim&e" -msgstr "时间编辑" - msgid "Bivariate Moran Variable Settings" msgstr "二元Moran变量设置" @@ -4051,7 +4084,7 @@ msgstr "其他正相关" msgid "Chinese Simplified (GB2312)" msgstr "中文简化版(GB23 12)" -msgid "&Delete" +msgid "Delete" msgstr "删除" msgid "Sample Autocorrelation" @@ -4117,9 +4150,6 @@ msgstr "条件G聚类地图变量" msgid "Please setup co-locations first." msgstr "请先设置Co-location。" -msgid "&Cancel" -msgstr "取消" - msgid "Specify bandwidth" msgstr "指定带宽" @@ -4180,9 +4210,6 @@ msgstr "数据类型" msgid "When \"all times\" selected for variable, result field must also be \"all times.\"" msgstr "当选择变量的时间为“all times”时, 保存结果的字段也必须选“all times”." -msgid "&Merge" -msgstr "合并" - msgid "calculating..." msgstr "计算中…" @@ -4225,7 +4252,7 @@ msgstr "保存泰森多边形" msgid "The selected variable is not numeric. Please select another variable." msgstr "所选变量不是数值类型,请选择其他变量。" -msgid "&Redo" +msgid "Redo" msgstr "重做" msgid "Your table cannot be aggregated because the key field \"%s\" is unique. Please use another key." @@ -4300,9 +4327,6 @@ msgstr "保存回归结果" msgid "Please select a time variable first, and make sure more than one time steps have been defined." msgstr "请首先选择一个时间变量, 并确保已定义了多个时间步长。" -msgid "Save" -msgstr "保存" - msgid "Read from an ASCII file" msgstr "从ASCII文件中读取" @@ -4542,3 +4566,93 @@ msgstr "属性" msgid "Value" msgstr "值" + +msgid "Add Map Layer" +msgstr "Add Map Layer" + +msgid "Edit Map Layer" +msgstr "Edit Map Layer" + +msgid "Map Layer Setting" +msgstr "Map Layer Setting" + +msgid "Set Highlight Association" +msgstr "Set Highlight Association" + +msgid "Clear Highlight Association" +msgstr "Clear Highlight Association" + +msgid "Change Fill Color" +msgstr "Change Fill Color" + +msgid "Change Outline Color" +msgstr "Change Outline Color" + +msgid "Outline Visible" +msgstr "Outline Visible" + +msgid "Only Map Boundary" +msgstr "Only Map Boundary" + +msgid "Change Point Radius" +msgstr "Change Point Radius" + +msgid "Set Association Dialog" +msgstr "Set Association Dialog" + +msgid "Select layer" +msgstr "Select layer" + +msgid "and field" +msgstr "and field" + +msgid "is associated to" +msgstr "is associated to" + +msgid "in current layer." +msgstr "in current layer." + +msgid "Show connect line" +msgstr "Show connect line" + +msgid "Point Radius:" +msgstr "Point Radius:" + +msgid "Map Layout Preview" +msgstr "Map Layout Preview" + +msgid "Show Legend" +msgstr "Show Legend" + +msgid "Use Transparent Legend Background" +msgstr "Use Transparent Legend Background" + +msgid "Image Dimension Setting" +msgstr "Image Dimension Setting" + +msgid "Width:" +msgstr "Width:" + +msgid "Height:" +msgstr "Height:" + +msgid "Resolution(dpi):" +msgstr "Resolution(dpi):" + +msgid "pixels" +msgstr "pixels" + +msgid "inches" +msgstr "inches" + +msgid "mm" +msgstr "mm" + +msgid "Basemap Sources: (Format: group_name.basemap_name,basemap_url)" +msgstr "Basemap Sources: (Format: group_name.basemap_name,basemap_url)" + +msgid "Basemap Parameters:" +msgstr "Basemap Parameters:" + +msgid "Multivariate Local Join Count" +msgstr "Multivariate Local Join Count" From 63cf999937bd82097945e8d670631f8e9eb2e7ad Mon Sep 17 00:00:00 2001 From: lixun910 Date: Sun, 29 Jul 2018 13:21:12 -0700 Subject: [PATCH 3/9] add build script for 1804 --- BuildTools/ubuntu/package/DEBIAN/control1804 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/BuildTools/ubuntu/package/DEBIAN/control1804 b/BuildTools/ubuntu/package/DEBIAN/control1804 index 9ca5981ff..2b6ed527c 100644 --- a/BuildTools/ubuntu/package/DEBIAN/control1804 +++ b/BuildTools/ubuntu/package/DEBIAN/control1804 @@ -4,7 +4,7 @@ Architecture: amd64 Priority: optional Section: graphics Installed-Size: 88128 -Depends: libgdal-dev, zlib1g, libexpat1, freeglut3, libreadline7, libgtk-3-0, libc-dev-bin, libssl1.0.0, libwebkitgtk-1.0-0 +Depends: libcurl4-openssl-dev, libgdal-dev, zlib1g, libexpat1, freeglut3, libreadline7, libgtk-3-0, libc-dev-bin, libssl1.0.0, libwebkitgtk-1.0-0 Maintainer: Luc Anselin < anselin@uchicago.edu > Provides: geoda Homepage: http://spatial.uchicago.edu From 793337bb7525865a34dd1156d1884ef08a604011 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 28 Sep 2018 15:52:50 -0700 Subject: [PATCH 4/9] #1679 zoom basemap and reset to nobasemap cause issue --- Explore/Basemap.cpp | 14 ++--- Explore/Basemap.h | 114 +++++++++++++++++++++++++++-------------- Explore/MapNewView.cpp | 82 +++++++++++++++-------------- Explore/MapNewView.h | 3 +- GdaShape.cpp | 9 ++++ GdaShape.h | 2 + GeoDa.cpp | 2 +- 7 files changed, 141 insertions(+), 85 deletions(-) diff --git a/Explore/Basemap.cpp b/Explore/Basemap.cpp index 7d0773f20..0986b5a0f 100644 --- a/Explore/Basemap.cpp +++ b/Explore/Basemap.cpp @@ -152,20 +152,22 @@ XY::XY(double _x, double _y) } -Basemap::Basemap(BasemapItem& basemap_item, +Basemap::Basemap(BasemapItem& _basemap_item, Screen* _screen, - MapLayer *_map, + MapLayer* _map, + MapLayer* _origMap, wxString _cachePath, OGRCoordinateTransformation *_poCT, double _scale_factor) { - poCT = _poCT; + basemap_item = _basemap_item; screen = _screen; map = _map; - scale_factor = _scale_factor; - origMap = new MapLayer(map); - + origMap = _origMap; cachePath = _cachePath; + poCT = _poCT; + scale_factor = _scale_factor; + bDownload = false; downloadThread = NULL; isPan = false; diff --git a/Explore/Basemap.h b/Explore/Basemap.h index 4e51a79e6..11c4ecc56 100644 --- a/Explore/Basemap.h +++ b/Explore/Basemap.h @@ -49,6 +49,11 @@ class BasemapItem { bool operator==(const BasemapItem& other) { return (group == other.group && name == other.name && url == other.url); } + void Reset() { + group = ""; + name = ""; + url = ""; + } wxString group; wxString name; wxString url; @@ -156,18 +161,32 @@ namespace GDA { class MapLayer { public: - MapLayer(){} + double north; + double south; + double west; + double east; + OGRCoordinateTransformation *poCT; + OGRCoordinateTransformation *poCT_rev; + + MapLayer(){ + poCT = NULL; + poCT_rev = NULL; + } MapLayer(MapLayer* _map) { north = _map->north; south = _map->south; west = _map->west; east = _map->east; + poCT = NULL; + poCT_rev = NULL; } MapLayer(double _n, double _w, double _s, double _e){ north = _n; south = _s; west = _w; east = _e; + poCT = NULL; + poCT_rev = NULL; } MapLayer(double _n, double _w, double _s, double _e, OGRCoordinateTransformation *_poCT){ @@ -176,6 +195,7 @@ namespace GDA { west = _w; east = _e; poCT = _poCT; + poCT_rev = NULL; if (poCT!= NULL) { if (poCT->Transform(1, &_w, &_n)) { west = _w; @@ -185,6 +205,7 @@ namespace GDA { east = _e; south = _s; } + poCT_rev = OGRCreateCoordinateTransformation(poCT->GetTargetCS(), poCT->GetSourceCS()); } } MapLayer(LatLng& nw, LatLng& se){ @@ -192,22 +213,28 @@ namespace GDA { west = nw.lng; south = se.lat; east = se.lng; + poCT = NULL; + poCT_rev = NULL; } - ~MapLayer(){} - - MapLayer* operator=(const MapLayer* other) { - north = other->north; - south = other->south; - west = other->west; - east = other->east; - return this; + ~MapLayer(){ + if (poCT) { + delete poCT; + } + if (poCT_rev) { + delete poCT_rev; + } } - double north; - double south; - double west; - double east; - OGRCoordinateTransformation *poCT; + void GetWestNorthEastSouth(double& w, double& n, double& e, double& s) { + if (poCT_rev) { + w = west; + n = north; + e = east; + s = south; + poCT_rev->Transform(1, &w, &n); + poCT_rev->Transform(1, &e, &s); + } + } double GetWidth() { if (east >= west) return east - west; @@ -258,18 +285,48 @@ namespace GDA { north = north + offsetH; south = south - offsetH; } + MapLayer* operator=(const MapLayer* other) { + north = other->north; + south = other->south; + west = other->west; + east = other->east; + poCT = NULL; + poCT_rev = NULL; + if (other->poCT) { + poCT = OGRCreateCoordinateTransformation(other->poCT->GetSourceCS(), other->poCT->GetTargetCS()); + } + if (other->poCT_rev) { + poCT_rev = OGRCreateCoordinateTransformation(other->poCT_rev->GetSourceCS(), other->poCT_rev->GetTargetCS()); + } + return this; + } }; // only for Web mercator projection class Basemap { + int nn; // pow(2.0, zoom) + bool bDownload; + boost::thread* downloadThread; + boost::thread* downloadThread1; + + int GetOptimalZoomLevel(double paddingFactor=1.2); + int GetEasyZoomLevel(); + + void GetTiles(); + void _GetTiles(int start_x, int start_y, int end_x, int end_y); + void _GetTiles(int x, int start_y, int end_y); + void DownloadTile(int x, int y); + + bool _HasInternet(); public: Basemap(){} Basemap(BasemapItem& basemap_item, - Screen *_screen, - MapLayer *_map, + Screen* _screen, + MapLayer* _map, + MapLayer* _origMap, wxString _cachePath, - OGRCoordinateTransformation *_poCT, + OGRCoordinateTransformation* _poCT, double scale_factor = 1.0); ~Basemap(); @@ -310,6 +367,7 @@ namespace GDA { double Deg2Rad (double degree) { return degree * M_PI / 180.0; } double Rad2Deg (double radians) { return radians * 180.0 / M_PI;} XY* LatLngToXY(LatLng &latlng); + XY* LatLngToRawXY(LatLng &latlng); LatLng* XYToLatLng(XY &xy, bool isLL=false); void LatLngToXY(double lng, double lat, int &x, int &y); @@ -331,27 +389,7 @@ namespace GDA { void SetupMapType(BasemapItem& basemap_item); void CleanCache(); - - protected: - - int nn; // pow(2.0, zoom) - - bool bDownload; - boost::thread* downloadThread; - boost::thread* downloadThread1; - - int GetOptimalZoomLevel(double paddingFactor=1.2); - int GetEasyZoomLevel(); - - XY* LatLngToRawXY(LatLng &latlng); - - void GetTiles(); - void _GetTiles(int start_x, int start_y, int end_x, int end_y); - void _GetTiles(int x, int start_y, int end_y); - - void DownloadTile(int x, int y); - - bool _HasInternet(); + }; } diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 433d4c999..36726cab2 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -533,13 +533,7 @@ void MapCanvas::ResetShapes() delete faded_layer_bm; faded_layer_bm = NULL; } - if (isDrawBasemap) { - if (basemap) { - basemap->origMap->west = last_scale_trans.orig_data_x_min; - basemap->origMap->east = last_scale_trans.orig_data_x_max; - basemap->origMap->south = last_scale_trans.orig_data_y_min; - basemap->origMap->north = last_scale_trans.orig_data_y_max; - } + if (basemap) { basemap->Reset(); } last_scale_trans.Reset(); @@ -560,14 +554,15 @@ void MapCanvas::ZoomShapes(bool is_zoomin) } if (isDrawBasemap) { - bool zoom_ok = basemap->Zoom(is_zoomin, sel2.x, sel2.y, sel1.x, sel1.y); - if (zoom_ok) { - ResizeSelectableShps(); + if (basemap) { + bool zoom_ok = basemap->Zoom(is_zoomin, sel2.x, sel2.y, sel1.x, sel1.y); + if (zoom_ok) { + ResizeSelectableShps(); + } } - return; + } else { + TemplateCanvas::ZoomShapes(is_zoomin); } - - TemplateCanvas::ZoomShapes(is_zoomin); } void MapCanvas::PanShapes() @@ -724,23 +719,14 @@ bool MapCanvas::InitBasemap() if (project->sourceSR != NULL) { int nGCS = project->sourceSR->GetEPSGGeogCS(); - //if (nGCS != 4326) { - //} OGRSpatialReference destSR; destSR.importFromEPSG(4326); poCT = OGRCreateCoordinateTransformation(project->sourceSR,&destSR); } GDA::Screen* screen = new GDA::Screen(screenW, screenH); - double shps_orig_ymax = last_scale_trans.data_y_max; - double shps_orig_xmin = last_scale_trans.data_x_min; - double shps_orig_ymin = last_scale_trans.data_y_min; - double shps_orig_xmax = last_scale_trans.data_x_max; - GDA::MapLayer* map = new GDA::MapLayer(shps_orig_ymax, - shps_orig_xmin, - shps_orig_ymin, - shps_orig_xmax, - poCT); - if (poCT == NULL && !map->IsWGS84Valid()) { + GDA::MapLayer* current_map = new GDA::MapLayer(last_scale_trans.data_y_max, last_scale_trans.data_x_min, last_scale_trans.data_y_min, last_scale_trans.data_x_max, poCT); + GDA::MapLayer* orig_map = new GDA::MapLayer(last_scale_trans.orig_data_y_max, last_scale_trans.orig_data_x_min, last_scale_trans.orig_data_y_min, last_scale_trans.orig_data_x_max, poCT); + if (poCT == NULL && !orig_map->IsWGS84Valid()) { isDrawBasemap = false; wxStatusBar* sb = 0; if (template_frame) { @@ -752,12 +738,32 @@ bool MapCanvas::InitBasemap() } return false; } else { - basemap = new GDA::Basemap(basemap_item, screen, map, GenUtils::GetBasemapCacheDir(), poCT, scale_factor); + basemap = new GDA::Basemap(basemap_item, screen, current_map, orig_map, GenUtils::GetBasemapCacheDir(), poCT, scale_factor); } } return true; } +void MapCanvas::SetNoBasemap() +{ + ResetBrushing(); + isDrawBasemap = false; + basemap_item.Reset(); + if ( basemap ) { + basemap->basemap_item = basemap_item; + // keep extent if zoom in/out + double w, e, s, n; + basemap->map->GetWestNorthEastSouth(w, n, e, s); + last_scale_trans.SetExtent(w, e, s, n); + ResizeSelectableShps(); + } + layerbase_valid = false; + layer0_valid = false; + layer1_valid = false; + layer2_valid = false; + ReDraw(); +} + bool MapCanvas::DrawBasemap(bool flag, BasemapItem& _basemap_item) { ResetBrushing(); @@ -776,10 +782,9 @@ bool MapCanvas::DrawBasemap(bool flag, BasemapItem& _basemap_item) } else { if ( basemap ) { basemap->basemap_item = basemap_item; - last_scale_trans.data_x_min = basemap->map->west; - last_scale_trans.data_x_max = basemap->map->east; - last_scale_trans.data_y_min = basemap->map->south; - last_scale_trans.data_y_max = basemap->map->north; + double w, e, s, n; + basemap->map->GetWestNorthEastSouth(w, n, e, s); + last_scale_trans.SetExtent(w, e, s, n); ResizeSelectableShps(); } } @@ -1052,9 +1057,7 @@ void MapCanvas::DrawHighlightedShapes(wxMemoryDC &dc, bool revert) } else { DrawHighlight(dc, this); //DrawHighlighted(dc, revert); - } - - + } } void MapCanvas::SetHighlight(int idx) @@ -1217,18 +1220,14 @@ void MapCanvas::RenderToDC(wxDC &dc, int w, int h) layer2_valid = false; if (isDrawBasemap) { - GDA::Screen *screen = NULL; if (print_detailed_basemap) { basemap_bm = new wxBitmap(w, h, 32); basemap_scale = 1.0; last_scale_trans.SetView(w, h); - screen = new GDA::Screen(w, h); } else { // scaled basemap basemap_bm = new wxBitmap; basemap_bm->CreateScaled(screen_w, screen_h, 32, basemap_scale); - //last_scale_trans.SetView(screen_w, screen_h); - screen = new GDA::Screen(screen_w, screen_h); } OGRCoordinateTransformation *poCT = NULL; if (project->sourceSR != NULL) { @@ -1240,8 +1239,8 @@ void MapCanvas::RenderToDC(wxDC &dc, int w, int h) double shps_orig_xmin = last_scale_trans.orig_data_x_min; double shps_orig_ymin = last_scale_trans.orig_data_y_min; double shps_orig_xmax = last_scale_trans.orig_data_x_max; - GDA::MapLayer *map = new GDA::MapLayer(shps_orig_ymax, shps_orig_xmin, shps_orig_ymin, shps_orig_xmax, poCT); - if (poCT && map->IsWGS84Valid()) { + GDA::MapLayer maplayer(shps_orig_ymax, shps_orig_xmin, shps_orig_ymin, shps_orig_xmax, poCT); + if (poCT && maplayer.IsWGS84Valid()) { if (print_detailed_basemap) { basemap->ResizeScreen(w, h); basemap->Refresh(); @@ -3185,6 +3184,11 @@ void MapFrame::OnMapTreeClose(wxWindowDestroyEvent& event) map_tree = NULL; } +void MapFrame::SetNoBasemap() +{ + ((MapCanvas*) template_canvas)->SetNoBasemap(); +} + void MapFrame::OnBasemapSelect(wxCommandEvent& event) { int menu_id = event.GetId(); diff --git a/Explore/MapNewView.h b/Explore/MapNewView.h index e167db8b3..e52c60f55 100644 --- a/Explore/MapNewView.h +++ b/Explore/MapNewView.h @@ -179,6 +179,7 @@ class MapCanvas : public TemplateCanvas, public CatClassifStateObserver, public bool is_hide = false); void CleanBasemapCache(); bool DrawBasemap(bool flag, BasemapItem& bm_item); + void SetNoBasemap(); void OnIdle(wxIdleEvent& event); void TranslucentLayer0(wxMemoryDC& dc); void RenderToSVG(wxDC& dc, int svg_w, int svg_h, int map_w, int map_h, @@ -377,7 +378,7 @@ class MapFrame : public TemplateFrame, public WeightsManStateObserver virtual void OnSelectableOutlineVisible(wxCommandEvent& event); virtual void OnChangeMapTransparency(); virtual void OnDrawBasemap(bool flag, BasemapItem& bm_item); - + void SetNoBasemap(); void OnBasemapSelect(wxCommandEvent& event); void OnClose(wxCloseEvent& event); void CleanBasemap(); diff --git a/GdaShape.cpp b/GdaShape.cpp index ca7154e28..11952d288 100644 --- a/GdaShape.cpp +++ b/GdaShape.cpp @@ -156,6 +156,15 @@ void GdaScaleTrans::SetFixedAspectRatio(bool fixed) calcAffineParams(); } +void GdaScaleTrans::SetExtent(double w, double e, double s, double n) +{ + data_x_min = w; + data_x_max = e; + data_y_min = s; + data_y_max = n; + calcAffineParams(); +} + /** x_min, y_min, x_max, y_max are the bounding box limits for the entire map. target_height and target_width are ignored if set to 0. They are used when a target size smaller than the normal maximum working area size is diff --git a/GdaShape.h b/GdaShape.h index 0eddf7a55..3f6b22999 100644 --- a/GdaShape.h +++ b/GdaShape.h @@ -82,6 +82,8 @@ struct GdaScaleTrans { void Zoom(bool is_zoomin, wxPoint& from, wxPoint& to); void ScrollView(int scroll_x, int scroll_y); + void SetExtent(double w, double e, double s, double n); + int GetXNudge(); wxRealPoint GetDataCenter(); diff --git a/GeoDa.cpp b/GeoDa.cpp index 4b6ef4ebb..503bbc2c3 100644 --- a/GeoDa.cpp +++ b/GeoDa.cpp @@ -1588,7 +1588,7 @@ void GdaFrame::OnSetNoBasemap(wxCommandEvent& event) if (!t) return; MapFrame* f = dynamic_cast(t); - //if (f) f->OnDrawBasemap(false,0); + if (f) f->SetNoBasemap(); } void GdaFrame::OnBasemapConfig(wxCommandEvent& event) From 61f8134d08982d24f1f5717f6c294777343ba3c5 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Fri, 28 Sep 2018 16:16:12 -0700 Subject: [PATCH 5/9] update for visulization issue on linux and windows --- Explore/Basemap.h | 7 +------ Explore/MapNewView.cpp | 2 +- TemplateCanvas.cpp | 6 ++++-- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/Explore/Basemap.h b/Explore/Basemap.h index 11c4ecc56..e3d5fe91d 100644 --- a/Explore/Basemap.h +++ b/Explore/Basemap.h @@ -217,12 +217,7 @@ namespace GDA { poCT_rev = NULL; } ~MapLayer(){ - if (poCT) { - delete poCT; - } - if (poCT_rev) { - delete poCT_rev; - } + } void GetWestNorthEastSouth(double& w, double& n, double& e, double& s) { diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 36726cab2..58b5c3d00 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -1311,7 +1311,7 @@ void MapCanvas::RenderToDC(wxDC &dc, int w, int h) layer1_dc.Clear(); if (isDrawBasemap) { wxImage im = basemap_bm->ConvertToImage(); -#ifdef __WIN32__ +#if defined(__WIN32__) || defined(__linux__) im.Rescale(w*basemap_scale, h*basemap_scale, wxIMAGE_QUALITY_HIGH); #endif layer1_dc.DrawBitmap(im, 0, 0); diff --git a/TemplateCanvas.cpp b/TemplateCanvas.cpp index 8a357f0be..942539f8e 100644 --- a/TemplateCanvas.cpp +++ b/TemplateCanvas.cpp @@ -1563,7 +1563,9 @@ void TemplateCanvas::OnMouseEvent(wxMouseEvent& event) sel2.x = sel2.x + (c_w/8); sel2.y = sel2.y + (c_h/8); ZoomShapes(false); - } + } else { + sel1 = sel2; + } selectstate = start; Refresh(false); } else if (event.RightDown()) { @@ -1647,7 +1649,7 @@ void TemplateCanvas::helper_PaintSelectionOutline(wxDC& dc) { if (is_showing_brush && (mousemode == select || mousemode == zoom || mousemode == zoomout)) { - if (sel1 != sel2 ) { + if (sel1 != sel2) { dc.SetBrush(*wxTRANSPARENT_BRUSH); dc.SetPen(*wxBLACK_PEN); if (brushtype == rectangle) { From c535f5ebc2b5bac08d203c6abd2b15f4aac6f2dd Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 1 Oct 2018 15:32:41 -0700 Subject: [PATCH 6/9] remove the 20 limit in unique values; remove the 60 limit in k-means - remove the 60 limit in k-means, replace by 100 and an option to custom enter - remove the 20 limit in unique values maps, and implement a rationale so that a slightly changed color codes are repeated when there are more than x categories --- DialogTools/KMeansDlg.cpp | 19 ++++++++-- DialogTools/KMeansDlg.h | 4 +- DialogTools/SpectralClusteringDlg.cpp | 21 ++++++++--- DialogTools/SpectralClusteringDlg.h | 3 +- Explore/Basemap.cpp | 24 ++++++------ Explore/Basemap.h | 16 ++++---- Explore/CatClassification.cpp | 54 ++++++++++++++------------- Explore/CatClassification.h | 2 +- Explore/MapLayoutView.cpp | 2 +- TemplateLegend.cpp | 8 ++++ ogl/bmpshape.cpp | 1 - 11 files changed, 94 insertions(+), 60 deletions(-) diff --git a/DialogTools/KMeansDlg.cpp b/DialogTools/KMeansDlg.cpp index aea0e9655..526e5ec64 100644 --- a/DialogTools/KMeansDlg.cpp +++ b/DialogTools/KMeansDlg.cpp @@ -84,11 +84,10 @@ void KClusterDlg::CreateControls() wxStaticText* st1 = new wxStaticText(panel, wxID_ANY, _("Number of Clusters:"), wxDefaultPosition, wxSize(128,-1)); - combo_n = new wxChoice(panel, wxID_ANY, wxDefaultPosition, wxSize(200,-1), 0, NULL); - max_n_clusters = num_obs < 60 ? num_obs : 60; + combo_n = new wxComboBox(panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxSize(200,-1), 0, NULL); + max_n_clusters = num_obs < 100 ? num_obs : 100; for (int i=2; iAppend(wxString::Format("%d", i)); - combo_n->SetSelection(3); gbox->Add(st1, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); gbox->Add(combo_n, 1, wxEXPAND); @@ -464,7 +463,19 @@ bool KClusterDlg::Run(vector& clusters) resetrandom(); } - int ncluster = combo_n->GetSelection() + 2; + int ncluster = 0; + wxString str_ncluster = combo_n->GetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + if (ncluster < 2 || ncluster > num_obs) { + wxString err_msg = _("Please enter a valid number of clusters."); + wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return false; + } + int transform = combo_tranform->GetSelection(); if (!GetInputData(transform,1)) diff --git a/DialogTools/KMeansDlg.h b/DialogTools/KMeansDlg.h index 01dc5dc93..d538e37df 100644 --- a/DialogTools/KMeansDlg.h +++ b/DialogTools/KMeansDlg.h @@ -24,7 +24,7 @@ #include #include #include - +#include #include "../FramesManager.h" #include "../VarTools.h" @@ -73,7 +73,7 @@ class KClusterDlg : public AbstractClusterDlg wxCheckBox* chk_seed; wxChoice* combo_method; - wxChoice* combo_n; + wxComboBox* combo_n; wxChoice* combo_cov; wxTextCtrl* m_textbox; wxTextCtrl* m_iterations; diff --git a/DialogTools/SpectralClusteringDlg.cpp b/DialogTools/SpectralClusteringDlg.cpp index 414a9a4c2..fa3634e98 100644 --- a/DialogTools/SpectralClusteringDlg.cpp +++ b/DialogTools/SpectralClusteringDlg.cpp @@ -106,10 +106,10 @@ void SpectralClusteringDlg::CreateControls() // NumberOfCluster Control wxStaticText* st1 = new wxStaticText(panel, wxID_ANY, _("Number of Clusters:"), wxDefaultPosition, wxSize(128,-1)); - combo_n = new wxChoice(panel, wxID_ANY); - int max_n_clusters = num_obs < 60 ? num_obs : 60; - for (int i=2; iAppend(wxString::Format("%d", i)); - combo_n->SetSelection(3); + combo_n = new wxComboBox(panel, wxID_ANY); + int max_n_clusters = num_obs < 100 ? num_obs : 100; + for (int i=2; iAppend(wxString::Format("%d", i)); gbox->Add(st1, 0, wxALIGN_CENTER_VERTICAL | wxRIGHT | wxLEFT, 10); gbox->Add(combo_n, 1, wxEXPAND); @@ -520,7 +520,18 @@ void SpectralClusteringDlg::OnOK(wxCommandEvent& event ) resetrandom(); } - int ncluster = combo_n->GetSelection() + 2; + int ncluster = 0; + wxString str_ncluster = combo_n->GetValue(); + long value_ncluster; + if (str_ncluster.ToLong(&value_ncluster)) { + ncluster = value_ncluster; + } + if (ncluster < 2 || ncluster > num_obs) { + wxString err_msg = _("Please enter a valid number of cluster."); + wxMessageDialog dlg(NULL, err_msg, _("Error"), wxOK | wxICON_ERROR); + dlg.ShowModal(); + return; + } wxString field_name = m_textbox->GetValue(); if (field_name.IsEmpty()) { diff --git a/DialogTools/SpectralClusteringDlg.h b/DialogTools/SpectralClusteringDlg.h index 2e2984044..96fdcd511 100644 --- a/DialogTools/SpectralClusteringDlg.h +++ b/DialogTools/SpectralClusteringDlg.h @@ -24,6 +24,7 @@ #include #include #include +#include #include "../FramesManager.h" #include "../VarTools.h" @@ -59,7 +60,7 @@ class SpectralClusteringDlg : public AbstractClusterDlg protected: wxCheckBox* chk_seed; wxChoice* combo_method; - wxChoice* combo_n; + wxComboBox* combo_n; wxChoice* combo_cov; wxTextCtrl* m_textbox; wxTextCtrl* m_iterations; diff --git a/Explore/Basemap.cpp b/Explore/Basemap.cpp index 0986b5a0f..0d9cee1ac 100644 --- a/Explore/Basemap.cpp +++ b/Explore/Basemap.cpp @@ -143,7 +143,7 @@ vector ExtractBasemapResources(wxString basemap_sources) { return groups; } -XY::XY(double _x, double _y) +XYFraction::XYFraction(double _x, double _y) { x = _x; y = _y; @@ -300,8 +300,8 @@ void Basemap::ResizeScreen(int _width, int _height) void Basemap::Pan(int x0, int y0, int x1, int y1) { - XY origXY((x0 + leftP + offsetX)/256.0, (y0 + topP + offsetY)/256.0); - XY newXY((x1 + leftP + offsetX)/256.0, (y1 + topP + offsetY)/256.0); + XYFraction origXY((x0 + leftP + offsetX)/256.0, (y0 + topP + offsetY)/256.0); + XYFraction newXY((x1 + leftP + offsetX)/256.0, (y1 + topP + offsetY)/256.0); LatLng* p0 = XYToLatLng(origXY, true); LatLng* p1 = XYToLatLng(newXY, true); @@ -333,8 +333,8 @@ bool Basemap::Zoom(bool is_zoomin, int x0, int y0, int x1, int y1) bottom = screen->height * 2 - bottom; } - XY origXY((left + leftP + offsetX)/256.0, (top + topP + offsetY)/256.0); - XY newXY((right + leftP + offsetX)/256.0, (bottom + topP + offsetY)/256.0); + XYFraction origXY((left + leftP + offsetX)/256.0, (top + topP + offsetY)/256.0); + XYFraction newXY((right + leftP + offsetX)/256.0, (bottom + topP + offsetY)/256.0); LatLng* p0 = XYToLatLng(origXY, true); LatLng* p1 = XYToLatLng(newXY, true); @@ -442,11 +442,11 @@ void Basemap::GetTiles() // following: http://wiki.openstreetmap.org/wiki/Slippy_map_tilenames // top-left / north-west LatLng nw(map->north, map->west); - XY* topleft = LatLngToRawXY(nw); + XYFraction* topleft = LatLngToRawXY(nw); // bottom-right / south-east LatLng se(map->south, map->east); - XY* bottomright = LatLngToRawXY(se); + XYFraction* bottomright = LatLngToRawXY(se); startX = topleft->GetXInt(); startY = topleft->GetYInt(); @@ -649,7 +649,7 @@ void Basemap::DownloadTile(int x, int y) } -LatLng* Basemap::XYToLatLng(XY &xy, bool isLL) +LatLng* Basemap::XYToLatLng(XYFraction &xy, bool isLL) { double x = xy.x; if (x > nn) @@ -664,22 +664,22 @@ LatLng* Basemap::XYToLatLng(XY &xy, bool isLL) return new LatLng(lat, lng); } -XY* Basemap::LatLngToRawXY(LatLng &latlng) +XYFraction* Basemap::LatLngToRawXY(LatLng &latlng) { double lat_rad = latlng.GetLatRad(); double x = (latlng.GetLngDeg() + 180.0 ) / 360.0 * nn; double y = (1.0 - log(tan(lat_rad) + 1.0 / cos(lat_rad)) / M_PI) / 2.0 * nn; - return new XY(x, y); + return new XYFraction(x, y); } -XY* Basemap::LatLngToXY(LatLng &latlng) +XYFraction* Basemap::LatLngToXY(LatLng &latlng) { double lat_rad = latlng.GetLatRad(); double x = (latlng.GetLngDeg() + 180.0 ) / 360.0 * nn; double y = (1.0 - log(tan(lat_rad) + 1.0 / cos(lat_rad)) / M_PI) / 2.0 * nn; int xp = (int)(x * 256 - leftP) - offsetX; int yp = (int)(y * 256 - topP) - offsetY; - return new XY(xp, yp); + return new XYFraction(xp, yp); } void Basemap::LatLngToXY(double lng, double lat, int &x, int &y) diff --git a/Explore/Basemap.h b/Explore/Basemap.h index e3d5fe91d..962314f7a 100644 --- a/Explore/Basemap.h +++ b/Explore/Basemap.h @@ -122,10 +122,10 @@ namespace GDA { double GetLngRad() {return lng * M_PI / 180.0;} }; - class XY { + class XYFraction { public: - XY(){} - XY(int _x, int _y) { + XYFraction(){} + XYFraction(int _x, int _y) { x = _x; y = _y; xint = _x; @@ -133,8 +133,8 @@ namespace GDA { xfrac = .0; yfrac = .0; } - XY(double _x, double _y); - ~XY(){} + XYFraction(double _x, double _y); + ~XYFraction(){} double x; double y; @@ -361,9 +361,9 @@ namespace GDA { double Deg2Rad (double degree) { return degree * M_PI / 180.0; } double Rad2Deg (double radians) { return radians * 180.0 / M_PI;} - XY* LatLngToXY(LatLng &latlng); - XY* LatLngToRawXY(LatLng &latlng); - LatLng* XYToLatLng(XY &xy, bool isLL=false); + XYFraction* LatLngToXY(LatLng &latlng); + XYFraction* LatLngToRawXY(LatLng &latlng); + LatLng* XYToLatLng(XYFraction &xy, bool isLL=false); void LatLngToXY(double lng, double lat, int &x, int &y); wxString GetTileUrl(int x, int y); diff --git a/Explore/CatClassification.cpp b/Explore/CatClassification.cpp index 6ea099721..521638379 100644 --- a/Explore/CatClassification.cpp +++ b/Explore/CatClassification.cpp @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -2089,35 +2090,38 @@ void CatClassification::PickColorSet(std::vector& color_vec, ColorScheme coltype, int num_color, bool reversed) { - - if (coltype == unique_color_scheme) { color_vec.resize(num_color, *wxBLUE); - wxColour unique_colors[20] = { - wxColour(166,206,227), - wxColour(31,120,180), - wxColour(178,223,138), - wxColour(51,160,44), - wxColour(251,154,153), - wxColour(227,26,28), - wxColour(253,191,111), - wxColour(255,127,0), - wxColour(106,61,154), - wxColour(255,255,153), - wxColour(177,89,40), - wxColour(255,255,179), - wxColour(190,186,218), - wxColour(251,128,114), - wxColour(128,177,211), - wxColour(179,222,105), - wxColour(252,205,229), - wxColour(217,217,217), - wxColour(188,128,189), - wxColour(204,235,197) + int unique_colors[20][3] = { + {166,206,227}, + {31,120,180}, + {178,223,138}, + {51,160,44}, + {251,154,153}, + {227,26,28}, + {253,191,111}, + {255,127,0}, + {106,61,154}, + {255,255,153}, + {177,89,40}, + {255,255,179}, + {190,186,218}, + {251,128,114}, + {128,177,211}, + {179,222,105}, + {252,205,229}, + {217,217,217}, + {188,128,189}, + {204,235,197} }; - + srand (0); for (int i = 0; i < num_color; i++) { - color_vec[i] = unique_colors[i]; + int* rgb = unique_colors[i % 20]; + int rnd = rand() * (i / 20); + int r = (rgb[0] + rnd) % 255; + int g = (rgb[1] + rnd) % 255; + int b = (rgb[2] + rnd) % 255; + color_vec[i].Set(r, g, b); } return; } diff --git a/Explore/CatClassification.h b/Explore/CatClassification.h index 9b2075905..84e683098 100644 --- a/Explore/CatClassification.h +++ b/Explore/CatClassification.h @@ -35,7 +35,7 @@ class TableInterface; namespace CatClassification { - const int max_num_categories = 20; + const int max_num_categories = 2000; enum CatClassifType { no_theme, hinge_15, hinge_30, quantile, percentile, diff --git a/Explore/MapLayoutView.cpp b/Explore/MapLayoutView.cpp index 8a519734a..8eb40d993 100644 --- a/Explore/MapLayoutView.cpp +++ b/Explore/MapLayoutView.cpp @@ -347,7 +347,7 @@ CanvasLayoutDialog::CanvasLayoutDialog(wxString _project_name, TemplateLegend* _ canvas->AddShape(legend_shape); legend_shape->SetX(50 + legend_shape->GetWidth()); - legend_shape->SetY(50 + legend_shape->GetHeight()); + legend_shape->SetY(120); legend_shape->MakeControlPoints(); legend_shape->SetMaintainAspectRatio(true); legend_shape->Show(false); diff --git a/TemplateLegend.cpp b/TemplateLegend.cpp index 88ae1565b..b4122f6d0 100644 --- a/TemplateLegend.cpp +++ b/TemplateLegend.cpp @@ -197,6 +197,11 @@ isDragDropAllowed(false) wxBoxSizer* box = new wxBoxSizer(wxHORIZONTAL); box->Add(this, 1, wxEXPAND|wxALL); parent->SetSizer(box); + + int numRect = template_canvas->cat_data.GetNumCategories(0); + int height = numRect * 20 + py; + SetVirtualSize(wxSize(-1,height)); + SetScrollRate(1, 1); } TemplateLegend::~TemplateLegend() @@ -454,6 +459,9 @@ void TemplateLegend::OnDraw(wxDC& dc) void TemplateLegend::Recreate() { recreate_labels = true; + int numRect = template_canvas->cat_data.GetNumCategories(0); + int height = numRect * 20 + py; + SetVirtualSize(wxSize(-1,height)); Refresh(); } diff --git a/ogl/bmpshape.cpp b/ogl/bmpshape.cpp index 76e833a73..1ff0bbd5a 100644 --- a/ogl/bmpshape.cpp +++ b/ogl/bmpshape.cpp @@ -198,7 +198,6 @@ void wxBitmapShape::SetCanvas(TemplateLegend* _tlegend) m_imgmap.Destroy(); m_imgmap = bm.ConvertToImage(); - SetSize(legend_width, legend_height); } } From ed0da65ed06d0985e0b7abe92207cbaea7c685eb Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 1 Oct 2018 16:14:30 -0700 Subject: [PATCH 7/9] not displaying selected records that are turned off #1719 --- Explore/MapLayer.cpp | 18 ++++-------------- Explore/MapLayer.hpp | 12 +++++++----- Explore/MapLayerTree.cpp | 23 ++++++++++++++++------- Explore/MapNewView.cpp | 12 ++++++++---- 4 files changed, 35 insertions(+), 30 deletions(-) diff --git a/Explore/MapLayer.cpp b/Explore/MapLayer.cpp index d0db36332..d12f1c4f2 100644 --- a/Explore/MapLayer.cpp +++ b/Explore/MapLayer.cpp @@ -17,9 +17,9 @@ point_radius(2), opacity(255), pen_size(1), show_boundary(false), -is_hide(true), map_boundary(NULL) { + is_hide = true; } BackgroundMapLayer::BackgroundMapLayer(wxString name, OGRLayerProxy* _layer_proxy, OGRSpatialReference* sr) @@ -32,10 +32,10 @@ point_radius(2), opacity(255), pen_size(1), show_boundary(false), -is_hide(false), map_boundary(NULL), show_connect_line(false) { + is_hide = false; num_obs = layer_proxy->GetNumRecords(); shape_type = layer_proxy->GetGdaGeometries(shapes, sr); // this is for map boundary only @@ -164,7 +164,7 @@ void BackgroundMapLayer::DrawHighlight(wxMemoryDC& dc, MapCanvas* map_canvas) } vector& ids = aid_idx[aid]; for (int j=0; jIsHide()) { dc.DrawLine(shapes[i]->center, associated_layer->GetShape(ids[j])->center); } } @@ -173,7 +173,7 @@ void BackgroundMapLayer::DrawHighlight(wxMemoryDC& dc, MapCanvas* map_canvas) // draw self highlight for (int i=0; ipaintSelf(dc); } } @@ -321,16 +321,6 @@ Shapefile::ShapeType BackgroundMapLayer::GetShapeType() return shape_type; } -void BackgroundMapLayer::SetHide(bool flag) -{ - is_hide = flag; -} - -bool BackgroundMapLayer::IsHide() -{ - return is_hide; -} - void BackgroundMapLayer::drawLegend(wxDC& dc, int x, int y, int w, int h) { wxPen pen(pen_color); diff --git a/Explore/MapLayer.hpp b/Explore/MapLayer.hpp index 755a6d466..6733efa7f 100644 --- a/Explore/MapLayer.hpp +++ b/Explore/MapLayer.hpp @@ -25,11 +25,14 @@ typedef pair Association; class AssociateLayerInt { +protected: + bool is_hide; + public: // primary key : AssociateLayer map associated_layers; map associated_lines; - + AssociateLayerInt() {} virtual ~AssociateLayerInt() {} @@ -48,6 +51,8 @@ class AssociateLayerInt associated_layers.clear(); } virtual GdaShape* GetShape(int i) = 0; + virtual void SetHide(bool flag) { is_hide = flag; } + virtual bool IsHide() { return is_hide; } }; @@ -66,7 +71,7 @@ class BackgroundMapLayer : public AssociateLayerInt int opacity; int pen_size; bool show_boundary; - bool is_hide; + public: OGRLayerProxy* layer_proxy; @@ -105,9 +110,6 @@ class BackgroundMapLayer : public AssociateLayerInt void SetName(wxString name); virtual wxString GetName(); - void SetHide(bool flag); - bool IsHide(); - void SetPenColour(wxColour& color); wxColour GetPenColour(); diff --git a/Explore/MapLayerTree.cpp b/Explore/MapLayerTree.cpp index 0d43b333a..415c42e02 100644 --- a/Explore/MapLayerTree.cpp +++ b/Explore/MapLayerTree.cpp @@ -830,7 +830,7 @@ void MapTree::DrawLegend(wxDC& dc, int x, int y, wxString text) dc.DrawLine(10, y+2, x, y+2); BackgroundMapLayer* ml = GetMapLayer(text); - + x = x + 45; // switch width dc.SetPen(*wxBLACK_PEN); if (text == current_map_title) { @@ -854,12 +854,15 @@ void MapTree::DrawLegend(wxDC& dc, int x, int y, wxString text) dc.DrawText(text, x, y); // draw switch button - if (ml == NULL) { - return; + AssociateLayerInt* ml_int; + if (ml) { + ml_int = ml; + } else { + ml_int = canvas; } wxString ds_thumb = "switch-on.png"; - if (ml->IsHide()) ds_thumb = "switch-off.png"; + if (ml_int->IsHide()) ds_thumb = "switch-off.png"; wxString file_path_str = GenUtils::GetSamplesDir() + ds_thumb; wxImage img; @@ -932,12 +935,18 @@ void MapTree::OnSwitchClick(wxMouseEvent& event) wxString map_name = map_titles[new_order[switch_idx]]; BackgroundMapLayer* ml = GetMapLayer(map_name); - + AssociateLayerInt* ml_int; if (ml) { - ml->SetHide(!ml->IsHide()); + ml_int = ml; + } else { + ml_int = canvas; + } + + if (ml_int) { + ml_int->SetHide(!ml_int->IsHide()); canvas->DisplayMapLayers(); Refresh(); - } + } } } diff --git a/Explore/MapNewView.cpp b/Explore/MapNewView.cpp index 58b5c3d00..2e1864426 100644 --- a/Explore/MapNewView.cpp +++ b/Explore/MapNewView.cpp @@ -196,6 +196,7 @@ print_detailed_basemap(false), maplayer_state(project_s->GetMapLayerState()) { wxLogMessage("MapCanvas::MapCanvas()"); + is_hide = false; layer_name = project->layername; bg_maps = project->CloneBackgroundMaps(); ds_name = project->GetDataSource()->GetOGRConnectStr(); @@ -877,7 +878,9 @@ void MapCanvas::DrawLayer0() BOOST_FOREACH( GdaShape* map, background_maps ) { map->paintSelf(dc); } - DrawSelectableShapes_dc(dc); + if (IsHide() == false) { + DrawSelectableShapes_dc(dc); + } BOOST_FOREACH( GdaShape* map, foreground_maps ) { map->paintSelf(dc); } @@ -2101,14 +2104,15 @@ void MapCanvas::DrawHighlight(wxMemoryDC& dc, MapCanvas* map_canvas) } vector& ids = aid_idx[aid]; for (int j=0; jIsHide()) { dc.DrawLine(selectable_shps[i]->center, associated_layer->GetShape(ids[j])->center); } } } } - - this->DrawHighlighted(dc, false); + if (IsHide() == false) { + this->DrawHighlighted(dc, false); + } } GdaShape* MapCanvas::GetShape(int i) From 80841c5cb7475365f6c10473cb65de4c62831769 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 1 Oct 2018 16:18:09 -0700 Subject: [PATCH 8/9] version numbers broken on macOS #1698 --- BuildTools/macosx/GeoDa-GDAL-Info.plist | 4 ++-- version.h | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/BuildTools/macosx/GeoDa-GDAL-Info.plist b/BuildTools/macosx/GeoDa-GDAL-Info.plist index a89de7f08..e49c3081a 100644 --- a/BuildTools/macosx/GeoDa-GDAL-Info.plist +++ b/BuildTools/macosx/GeoDa-GDAL-Info.plist @@ -21,9 +21,9 @@ CFBundlePackageType APPL CFBundleSignature - ???? + io.gitub.geodacenter CFBundleVersion - 1.0 + 1.12 DTCompiler 4.2 DTPlatformBuild diff --git a/version.h b/version.h index 9b4f2fc0a..9c2f1227b 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 12; const int version_build = 1; - const int version_subbuild = 165; + const int version_subbuild = 167; const int version_year = 2018; - const int version_month = 9; - const int version_day = 25; + const int version_month = 10; + const int version_day = 1; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release } From 492f610494f555a7a0fa1eb5107043d8eec409e8 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Mon, 1 Oct 2018 16:22:01 -0700 Subject: [PATCH 9/9] update basemap sources --- GdaConst.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/GdaConst.cpp b/GdaConst.cpp index d1e284ea9..5237502ed 100644 --- a/GdaConst.cpp +++ b/GdaConst.cpp @@ -366,12 +366,12 @@ wxString GdaConst::gda_basemap_sources = "\nStamen.Toner,https://stamen-tiles-a.a.ssl.fastly.net/toner/{z}/{x}/{y}@2x.png" "\nStamen.TonerLite,https://stamen-tiles-a.a.ssl.fastly.net/toner-lite/{z}/{x}/{y}@2x.png" "\nStamen.Watercolor,https://stamen-tiles-a.a.ssl.fastly.net/watercolor/{z}/{x}/{y}@2x.png" -"\nOther.高德,http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}" -"\nOther.高德(卫星),http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}" -"\nOther.高德(卫星有标签),http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}" -"\nOther.天地图,http://t0.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}" -"\nOther.天地图(卫星),http://t0.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}" -"\nOther.天地图(地形),http://t0.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}" +"\nOther.AMAP,http://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}" +"\nOther.AMAP(Satellite),http://webst01.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}" +"\nOther.AMAP(SatelliteLabel),http://webst01.is.autonavi.com/appmaptile?style=8&x={x}&y={y}&z={z}" +"\nOther.TianDiTu,http://t0.tianditu.cn/DataServer?T=vec_w&X={x}&Y={y}&L={z}" +"\nOther.TianDiTu(Satellite),http://t0.tianditu.cn/DataServer?T=cia_w&X={x}&Y={y}&L={z}" +"\nOther.TianDiTu(Terrain),http://t0.tianditu.cn/DataServer?T=cta_w&X={x}&Y={y}&L={z}" ;