Improved MapProjection.Center handling

This commit is contained in:
Clemens 2022-03-06 17:28:27 +01:00
parent f52281ba85
commit 123a9916eb
5 changed files with 32 additions and 11 deletions

View file

@ -734,7 +734,10 @@ namespace MapControl
var viewScale = ViewTransform.ZoomLevelToScale(ZoomLevel); var viewScale = ViewTransform.ZoomLevelToScale(ZoomLevel);
var projection = MapProjection; var projection = MapProjection;
if (projection.Type == MapProjectionType.Azimuthal)
{
projection.Center = ProjectionCenter ?? Center; projection.Center = ProjectionCenter ?? Center;
}
var mapCenter = projection.LocationToMap(transformCenter ?? Center); var mapCenter = projection.LocationToMap(transformCenter ?? Center);
@ -767,7 +770,11 @@ namespace MapControl
{ {
ResetTransformCenter(); ResetTransformCenter();
projection.Center = ProjectionCenter ?? center; if (projection.Type == MapProjectionType.Azimuthal)
{
projection.Center = ProjectionCenter ?? Center;
}
mapCenter = projection.LocationToMap(center); mapCenter = projection.LocationToMap(center);
if (MapProjection.IsValid(mapCenter)) if (MapProjection.IsValid(mapCenter))

View file

@ -44,7 +44,7 @@ namespace MapControl
public string CrsId { get; protected set; } = string.Empty; public string CrsId { get; protected set; } = string.Empty;
/// <summary> /// <summary>
/// Gets or sets the projection center. /// Gets or sets an optional projection center.
/// </summary> /// </summary>
public Location Center { get; set; } = new Location(); public Location Center { get; set; } = new Location();

View file

@ -137,20 +137,30 @@ namespace MapControl
var latPoints = latSegments * interpolationCount; var latPoints = latSegments * interpolationCount;
var centerLon = Math.Round(ParentMap.Center.Longitude / lineDistance) * lineDistance; var centerLon = Math.Round(ParentMap.Center.Longitude / lineDistance) * lineDistance;
var westLimit = centerLon - 180d;
var eastLimit = centerLon + 180d;
if (ParentMap.MapProjection.Type == MapProjectionType.TransverseCylindrical)
{
westLimit = ParentMap.MapProjection.Center.Longitude - 15d;
eastLimit = ParentMap.MapProjection.Center.Longitude + 15d;
westLimit = Math.Floor(westLimit / lineDistance) * lineDistance;
eastLimit = Math.Ceiling(eastLimit / lineDistance) * lineDistance;
}
var minLon = centerLon - lineDistance; var minLon = centerLon - lineDistance;
var maxLon = centerLon + lineDistance; var maxLon = centerLon + lineDistance;
var lonRange = ParentMap.MapProjection.Type == MapProjectionType.TransverseCylindrical ? 15d : 180d;
if (DrawMeridian(path.Figures, centerLon, minLat, interpolationDistance, latPoints)) if (DrawMeridian(path.Figures, centerLon, minLat, interpolationDistance, latPoints))
{ {
while (DrawMeridian(path.Figures, minLon, minLat, interpolationDistance, latPoints) && while (DrawMeridian(path.Figures, minLon, minLat, interpolationDistance, latPoints) &&
minLon > centerLon - lonRange) minLon > westLimit)
{ {
minLon -= lineDistance; minLon -= lineDistance;
} }
while (DrawMeridian(path.Figures, maxLon, minLat, interpolationDistance, latPoints) && while (DrawMeridian(path.Figures, maxLon, minLat, interpolationDistance, latPoints) &&
maxLon <= centerLon + lonRange) maxLon < eastLimit)
{ {
maxLon += lineDistance; maxLon += lineDistance;
} }

View file

@ -25,6 +25,7 @@ namespace MapControl.Projections
public class GeoApiProjection : MapProjection public class GeoApiProjection : MapProjection
{ {
private ICoordinateSystem coordinateSystem; private ICoordinateSystem coordinateSystem;
private Location center;
private double scaleFactor; private double scaleFactor;
private string bboxFormat; private string bboxFormat;
@ -100,6 +101,10 @@ namespace MapControl.Projections
Type = MapProjectionType.TransverseCylindrical; Type = MapProjectionType.TransverseCylindrical;
} }
Center = new Location(
centralParallel != null ? centralParallel.Value : 0d,
centralMeridian != null ? centralMeridian.Value : 0d);
scaleFactor = 1d; scaleFactor = 1d;
bboxFormat = "{0},{1},{2},{3}"; bboxFormat = "{0},{1},{2},{3}";
} }

View file

@ -19,7 +19,6 @@ namespace MapControl.Projections
public static double ConvergenceTolerance { get; set; } = 1e-6; public static double ConvergenceTolerance { get; set; } = 1e-6;
public static int MaxIterations { get; set; } = 10; public static int MaxIterations { get; set; } = 10;
public bool IsNorth { get; }
public double ScaleFactor { get; } public double ScaleFactor { get; }
public double FalseEasting { get; } public double FalseEasting { get; }
public double FalseNorthing { get; } public double FalseNorthing { get; }
@ -27,7 +26,7 @@ namespace MapControl.Projections
public PolarStereographicProjection(string crsId, bool isNorth, double scaleFactor, double falseEasting, double falseNorthing) public PolarStereographicProjection(string crsId, bool isNorth, double scaleFactor, double falseEasting, double falseNorthing)
{ {
CrsId = crsId; CrsId = crsId;
IsNorth = isNorth; Center = new Location(isNorth ? 90d : -90d, 0d);
ScaleFactor = scaleFactor; ScaleFactor = scaleFactor;
FalseEasting = falseEasting; FalseEasting = falseEasting;
FalseNorthing = falseNorthing; FalseNorthing = falseNorthing;
@ -35,7 +34,7 @@ namespace MapControl.Projections
public override Vector GetRelativeScale(Location location) public override Vector GetRelativeScale(Location location)
{ {
var lat = (IsNorth ? location.Latitude : -location.Latitude) * Math.PI / 180d; var lat = Math.Sign(Center.Latitude) * location.Latitude * Math.PI / 180d;
var a = Wgs84EquatorialRadius; var a = Wgs84EquatorialRadius;
var e = Wgs84Eccentricity; var e = Wgs84Eccentricity;
var s = Math.Sqrt(Math.Pow(1 + e, 1 + e) * Math.Pow(1 - e, 1 - e)); var s = Math.Sqrt(Math.Pow(1 + e, 1 + e) * Math.Pow(1 - e, 1 - e));
@ -53,7 +52,7 @@ namespace MapControl.Projections
var lat = location.Latitude * Math.PI / 180d; var lat = location.Latitude * Math.PI / 180d;
var lon = location.Longitude * Math.PI / 180d; var lon = location.Longitude * Math.PI / 180d;
if (IsNorth) if (Center.Latitude > 0d)
{ {
lon = Math.PI - lon; lon = Math.PI - lon;
} }
@ -92,7 +91,7 @@ namespace MapControl.Projections
lat = newLat; lat = newLat;
} }
if (IsNorth) if (Center.Latitude > 0d)
{ {
lon = Math.PI - lon; lon = Math.PI - lon;
} }