From abd6a566cb728cfab0486c1471efb67c4d23b330 Mon Sep 17 00:00:00 2001 From: "Sergey V. Zhdanovskih" Date: Sat, 2 Nov 2024 00:37:59 +0300 Subject: [PATCH] Added setting of default base point on maps depending on user locale --- locales/locales.yaml | 30 +++++++++ projects/GKCore/GKCore.csproj | 7 ++ projects/GKCore/GKCore.nstd.csproj | 4 ++ projects/GKCore/GKCore/AppHost.cs | 17 +++++ .../Controllers/MapsViewerWinController.cs | 35 ++++++++++ .../GKCore/Design/Controls/IMapBrowser.cs | 4 ++ projects/GKCore/GKCore/LocalesCollection.cs | 67 +++++++++++++++++++ projects/GKMap/GKMap.Core/IMapControl.cs | 10 ++- .../GKMap/GKMap.Core/MapObjects/MapOverlay.cs | 4 +- .../GKMap.Core/MapProviders/GMapProvider.cs | 11 ++- projects/GKMap/GKMap.EtoForms/GMapControl.cs | 4 +- projects/GKMap/GKMap.WinForms/GMapControl.cs | 4 +- projects/GKMap/GKMap.Xamarin/GMapControl.cs | 4 +- .../GKUI/Components/GKMapBrowser.cs | 11 +-- .../GKUI/Components/GKMapBrowser.cs | 11 +-- .../GKUI/Components/GKMapBrowser.cs | 11 +-- 16 files changed, 190 insertions(+), 44 deletions(-) create mode 100644 locales/locales.yaml create mode 100644 projects/GKCore/GKCore/LocalesCollection.cs diff --git a/locales/locales.yaml b/locales/locales.yaml new file mode 100644 index 000000000..717e17fe0 --- /dev/null +++ b/locales/locales.yaml @@ -0,0 +1,30 @@ +--- +- Locale: 'af-ZA' + MapBasePoint: 'South Africa, Pretoria' +- Locale: 'be-BY' + MapBasePoint: 'Беларусь, Мінск' +- Locale: 'cs-CZ' + MapBasePoint: 'Czechia, Prague' +- Locale: 'es-ES' + MapBasePoint: 'Spain, Madrid' +- Locale: 'hu-HU' + MapBasePoint: 'Hungary, Budapest' +- Locale: 'is-IS' + MapBasePoint: 'Iceland, Reykjavík' +- Locale: 'it-IT' + MapBasePoint: 'Italy, Rome' +- Locale: 'ja-JP' + MapBasePoint: 'Japan, Tokyo' +- Locale: 'kk-KZ' + MapBasePoint: 'Kazakhstan, Astana' +- Locale: 'nl-NL' + MapBasePoint: 'Netherlands, Amsterdam' +- Locale: 'pt-PT' + MapBasePoint: 'Portugal, Lisbon' +- Locale: 'ru-RU' + MapBasePoint: 'Российская Федерация, Москва' +- Locale: 'sr-Latn-RS' + MapBasePoint: 'Serbia, Belgrade' +- Locale: 'zh-CN' + MapBasePoint: 'China, Beijing' +... diff --git a/projects/GKCore/GKCore.csproj b/projects/GKCore/GKCore.csproj index ef1f1577e..e68c6ee1c 100644 --- a/projects/GKCore/GKCore.csproj +++ b/projects/GKCore/GKCore.csproj @@ -551,6 +551,13 @@ + + + + + {D0C39D9D-BED0-418B-9A5E-713176CAF40C} + GKMap.Core + diff --git a/projects/GKCore/GKCore.nstd.csproj b/projects/GKCore/GKCore.nstd.csproj index e3f4aafcd..5c1bf54a5 100644 --- a/projects/GKCore/GKCore.nstd.csproj +++ b/projects/GKCore/GKCore.nstd.csproj @@ -42,6 +42,10 @@ + + + + diff --git a/projects/GKCore/GKCore/AppHost.cs b/projects/GKCore/GKCore/AppHost.cs index 95572e719..6ce1a7fde 100644 --- a/projects/GKCore/GKCore/AppHost.cs +++ b/projects/GKCore/GKCore/AppHost.cs @@ -80,6 +80,7 @@ public abstract class AppHost : IHost, ISingleInstanceEnforcer private ITimer fAutosaveTimer; private string[] fCommandArgs; private int fLoadingCount; + private LocalesCollection fLocalesCollection; public static AppHost Instance @@ -93,6 +94,11 @@ public IList ActiveWidgets get { return fActiveWidgets; } } + public LocalesCollection LocalesCollection + { + get { return fLocalesCollection; } + } + protected AppHost() { @@ -102,6 +108,7 @@ protected AppHost() fInternalClipboard = new List(); fRunningForms = new List(); fTips = new StringList(); + fLocalesCollection = new LocalesCollection(); } protected virtual void ApplicationExit() @@ -168,6 +175,7 @@ public virtual async void StartupWork() ProcessHolidays(); ProcessTips(); + ProcessLocales(); await EndLoading(); } finally { @@ -916,6 +924,15 @@ public async Task ReloadRecentBases() return result; } + public void ProcessLocales() + { + try { + fLocalesCollection.Load(GKUtils.GetLangsPath() + "locales.yaml"); + } catch (Exception ex) { + Logger.WriteError("AppHost.ProcessLocales()", ex); + } + } + public void ProcessHolidays() { try { diff --git a/projects/GKCore/GKCore/Controllers/MapsViewerWinController.cs b/projects/GKCore/GKCore/Controllers/MapsViewerWinController.cs index 4c06edf83..a3382fc5d 100644 --- a/projects/GKCore/GKCore/Controllers/MapsViewerWinController.cs +++ b/projects/GKCore/GKCore/Controllers/MapsViewerWinController.cs @@ -20,6 +20,7 @@ using System; using System.Collections.Generic; +using System.Globalization; using BSLib; using GDModel; using GDModel.Providers.GEDCOM; @@ -29,6 +30,8 @@ using GKCore.Interfaces; using GKCore.Maps; using GKCore.Options; +using GKMap; +using GKMap.MapProviders; namespace GKCore.Controllers { @@ -57,6 +60,38 @@ public MapsViewerWinController(IMapsViewerWin view, List selectedPers fSearchPlacesWithoutCoords = GlobalOptions.Instance.SearchPlacesWithoutCoords; } + public override void Init(IBaseWindow baseWin) + { + base.Init(baseWin); + + CultureInfo culture = CultureInfo.CurrentCulture; + string basePoint = AppHost.Instance.LocalesCollection.GetMapBasePoint(culture.Name); + + // add start location + PointLatLng? pos = null; + GeocoderStatusCode status = GeocoderStatusCode.Unknown; + + if (!string.IsNullOrEmpty(basePoint)) { + //GMapProvider.LanguageStr = culture.TwoLetterISOLanguageName; + //pos = GMapProviders.GoogleMap.GetPoint(basePoint, out status); + + var pointsList = new List(); + PlacesCache.Instance.GetPlacePoints(basePoint, pointsList); + if (pointsList.Count > 0) { + var pt = pointsList[0]; + pos = new PointLatLng(pt.Latitude, pt.Longitude); + status = GeocoderStatusCode.Success; + } + } + + if (pos == null || status != GeocoderStatusCode.Success) { + pos = new PointLatLng(-15.950278, -5.683056); + } + + fView.MapBrowser.TargetPosition = pos.Value; + fView.MapBrowser.MapControl.ZoomAndCenterMarkers(null); + } + public void ShowFixedPoints(IEnumerable points) { var mapBrowser = fView.MapBrowser; diff --git a/projects/GKCore/GKCore/Design/Controls/IMapBrowser.cs b/projects/GKCore/GKCore/Design/Controls/IMapBrowser.cs index df589eed2..8d9b03e51 100644 --- a/projects/GKCore/GKCore/Design/Controls/IMapBrowser.cs +++ b/projects/GKCore/GKCore/Design/Controls/IMapBrowser.cs @@ -20,6 +20,7 @@ using System.Collections.Generic; using GKCore.Maps; +using GKMap; namespace GKCore.Design.Controls { @@ -28,9 +29,12 @@ namespace GKCore.Design.Controls /// public interface IMapBrowser : IBaseControl { + IMapControl MapControl { get; } + bool ShowPoints { get; set; } bool ShowLines { get; set; } IList MapPoints { get; } + PointLatLng TargetPosition { get; set; } int AddPoint(double latitude, double longitude, string hint); int AddPoint(GeoPoint pt); diff --git a/projects/GKCore/GKCore/LocalesCollection.cs b/projects/GKCore/GKCore/LocalesCollection.cs new file mode 100644 index 000000000..649354c39 --- /dev/null +++ b/projects/GKCore/GKCore/LocalesCollection.cs @@ -0,0 +1,67 @@ +/* + * "GEDKeeper", the personal genealogical database editor. + * Copyright (C) 2009-2024 by Sergey V. Zhdanovskih. + * + * This file is part of "GEDKeeper". + * + * This program 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. + * + * This program 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 . + */ + +using System; +using System.IO; +using System.Linq; + +namespace GKCore +{ + public sealed class LocaleInfo + { + public string Locale; + public string MapBasePoint; + } + + + /// + /// + /// + public sealed class LocalesCollection + { + private LocaleInfo[] fList; + + public LocalesCollection() + { + fList = new LocaleInfo[0]; + } + + public void Load(string fileName) + { + if (!File.Exists(fileName)) + return; + + try { + using (var reader = new StreamReader(fileName)) { + string content = reader.ReadToEnd(); + fList = YamlHelper.Deserialize(content); + } + } catch (Exception ex) { + Logger.WriteError("LocalesCollection.Load()", ex); + } + } + + public string GetMapBasePoint(string locale) + { + var locInfo = fList.FirstOrDefault((x) => x.Locale == locale); + return (locInfo == null) ? null : locInfo.MapBasePoint; + } + } +} diff --git a/projects/GKMap/GKMap.Core/IMapControl.cs b/projects/GKMap/GKMap.Core/IMapControl.cs index 631237009..c9b6f2d79 100644 --- a/projects/GKMap/GKMap.Core/IMapControl.cs +++ b/projects/GKMap/GKMap.Core/IMapControl.cs @@ -25,12 +25,10 @@ namespace GKMap public delegate void RouteEnter(MapRoute item); public delegate void RouteLeave(MapRoute item); - internal interface IMapControl + public interface IMapControl { string CacheLocation { get; set; } - MapCore Core { get; } - GMapProvider MapProvider { get; set; } int MaxZoom { get; set; } @@ -79,4 +77,10 @@ internal interface IMapControl #endregion } + + + internal interface IMapControlEx : IMapControl + { + MapCore Core { get; } + } } diff --git a/projects/GKMap/GKMap.Core/MapObjects/MapOverlay.cs b/projects/GKMap/GKMap.Core/MapObjects/MapOverlay.cs index 56cc75479..b611a3ef7 100644 --- a/projects/GKMap/GKMap.Core/MapObjects/MapOverlay.cs +++ b/projects/GKMap/GKMap.Core/MapObjects/MapOverlay.cs @@ -15,7 +15,7 @@ namespace GKMap.MapObjects /// public abstract class MapOverlay : IDisposable { - private IMapControl fControl; + private IMapControlEx fControl; private bool fDisposed; private bool fIsHitTestVisible = true; private bool fIsVisible = true; @@ -97,7 +97,7 @@ public bool IsZoomSignificant /// public ObservableCollectionThreadSafe Polygons { get; private set; } - internal IMapControl Control + internal IMapControlEx Control { get { return fControl; diff --git a/projects/GKMap/GKMap.Core/MapProviders/GMapProvider.cs b/projects/GKMap/GKMap.Core/MapProviders/GMapProvider.cs index 9d25ff480..2eb9370ec 100644 --- a/projects/GKMap/GKMap.Core/MapProviders/GMapProvider.cs +++ b/projects/GKMap/GKMap.Core/MapProviders/GMapProvider.cs @@ -172,16 +172,15 @@ protected GMapProvider() /// public bool InvertedAxisY = false; + /// + /// map language + /// public static string LanguageStr { - get { - return fLanguageStr; - } + get { return fLanguageStr; } + set { fLanguageStr = value; } } - /// - /// map language - /// public static LanguageType Language { get { diff --git a/projects/GKMap/GKMap.EtoForms/GMapControl.cs b/projects/GKMap/GKMap.EtoForms/GMapControl.cs index 3671726d3..3e51e5223 100644 --- a/projects/GKMap/GKMap.EtoForms/GMapControl.cs +++ b/projects/GKMap/GKMap.EtoForms/GMapControl.cs @@ -33,7 +33,7 @@ namespace GKMap.EtoForms /// /// GKMap control for Windows Forms /// - public class GMapControl : Drawable, IMapControl + public class GMapControl : Drawable, IMapControlEx { public static readonly bool IsDesignerHosted = LicenseManager.UsageMode == LicenseUsageMode.Designtime; @@ -76,7 +76,7 @@ public string CacheLocation } } - MapCore IMapControl.Core { get { return fCore; } } + MapCore IMapControlEx.Core { get { return fCore; } } /// /// stops immediate marker/route/polygon invalidation; diff --git a/projects/GKMap/GKMap.WinForms/GMapControl.cs b/projects/GKMap/GKMap.WinForms/GMapControl.cs index b65e80a6e..8226d254e 100644 --- a/projects/GKMap/GKMap.WinForms/GMapControl.cs +++ b/projects/GKMap/GKMap.WinForms/GMapControl.cs @@ -36,7 +36,7 @@ namespace GKMap.WinForms /// /// GKMap control for Windows Forms /// - public class GMapControl : UserControl, IMapControl + public class GMapControl : UserControl, IMapControlEx { public static readonly bool IsDesignerHosted = LicenseManager.UsageMode == LicenseUsageMode.Designtime; @@ -83,7 +83,7 @@ public string CacheLocation } } - MapCore IMapControl.Core { get { return fCore; } } + MapCore IMapControlEx.Core { get { return fCore; } } /// /// stops immediate marker/route/polygon invalidation; diff --git a/projects/GKMap/GKMap.Xamarin/GMapControl.cs b/projects/GKMap/GKMap.Xamarin/GMapControl.cs index 330c2488e..dca13877e 100644 --- a/projects/GKMap/GKMap.Xamarin/GMapControl.cs +++ b/projects/GKMap/GKMap.Xamarin/GMapControl.cs @@ -31,7 +31,7 @@ namespace GKMap.Xamarin /// /// GKMap control for Windows Forms /// - public class GMapControl : SKCanvasView, IMapControl + public class GMapControl : SKCanvasView, IMapControlEx { private MapCore fCore; private bool fIsMouseOverMarker; @@ -66,7 +66,7 @@ public string CacheLocation } } - MapCore IMapControl.Core { get { return fCore; } } + MapCore IMapControlEx.Core { get { return fCore; } } /// /// stops immediate marker/route/polygon invalidation; diff --git a/projects/GKv2/GKComponents/GKUI/Components/GKMapBrowser.cs b/projects/GKv2/GKComponents/GKUI/Components/GKMapBrowser.cs index 2cc45de06..c9850de85 100644 --- a/projects/GKv2/GKComponents/GKUI/Components/GKMapBrowser.cs +++ b/projects/GKv2/GKComponents/GKUI/Components/GKMapBrowser.cs @@ -193,7 +193,7 @@ public void ZoomToBounds() private GMapControl fMapControl; private MapMarker fTargetMarker; - public GMapControl MapControl + public IMapControl MapControl { get { return fMapControl; } } @@ -206,6 +206,7 @@ public GMapOverlay Objects public PointLatLng TargetPosition { get { return fTargetMarker.Position; } + set { fTargetMarker.Position = value; } } private void InitControl() @@ -260,14 +261,6 @@ private void InitControl() fTargetMarker.IsHitTestVisible = false; fTargetMarker.IsVisible = true; fTopOverlay.Markers.Add(fTargetMarker); - - // add start location - GeocoderStatusCode status; - PointLatLng? pos = GMapProviders.GoogleMap.GetPoint("Russia, Moscow", out status); - if (pos != null && status == GeocoderStatusCode.Success) { - fTargetMarker.Position = pos.Value; - fMapControl.ZoomAndCenterMarkers(null); - } } } diff --git a/projects/GKv3/GKComponents/GKUI/Components/GKMapBrowser.cs b/projects/GKv3/GKComponents/GKUI/Components/GKMapBrowser.cs index 886cab3de..19c029c89 100644 --- a/projects/GKv3/GKComponents/GKUI/Components/GKMapBrowser.cs +++ b/projects/GKv3/GKComponents/GKUI/Components/GKMapBrowser.cs @@ -195,7 +195,7 @@ public void ZoomToBounds() private GMapControl fMapControl; private MapMarker fTargetMarker; - public GMapControl MapControl + public IMapControl MapControl { get { return fMapControl; } } @@ -208,6 +208,7 @@ public GMapOverlay Objects public PointLatLng TargetPosition { get { return fTargetMarker.Position; } + set { fTargetMarker.Position = value; } } private void InitControl() @@ -260,14 +261,6 @@ private void InitControl() fTargetMarker.IsHitTestVisible = false; fTargetMarker.IsVisible = true; fTopOverlay.Markers.Add(fTargetMarker); - - // add start location - GeocoderStatusCode status; - PointLatLng? pos = GMapProviders.GoogleMap.GetPoint("Russia, Moscow", out status); - if (pos != null && status == GeocoderStatusCode.Success) { - fTargetMarker.Position = pos.Value; - fMapControl.ZoomAndCenterMarkers(null); - } } } diff --git a/projects/GKvX/GEDKeeperX/GKUI/Components/GKMapBrowser.cs b/projects/GKvX/GEDKeeperX/GKUI/Components/GKMapBrowser.cs index 5ce2171a8..575f2f918 100644 --- a/projects/GKvX/GEDKeeperX/GKUI/Components/GKMapBrowser.cs +++ b/projects/GKvX/GEDKeeperX/GKUI/Components/GKMapBrowser.cs @@ -187,7 +187,7 @@ public void ZoomToBounds() private GMapControl fMapControl; private MapMarker fTargetMarker; - public GMapControl MapControl + public IMapControl MapControl { get { return fMapControl; } } @@ -200,6 +200,7 @@ public GMapOverlay Objects public PointLatLng TargetPosition { get { return fTargetMarker.Position; } + set { fTargetMarker.Position = value; } } private void InitControl() @@ -253,14 +254,6 @@ private void InitControl() fTargetMarker.IsHitTestVisible = false; fTargetMarker.IsVisible = true; fTopOverlay.Markers.Add(fTargetMarker); - - // add start location - GeocoderStatusCode status; - PointLatLng? pos = GMapProviders.OpenStreetMap.GetPoint("Russia, Moscow", out status); - if (pos != null && status == GeocoderStatusCode.Success) { - fTargetMarker.Position = pos.Value; - fMapControl.ZoomAndCenterMarkers(null); - } } }