在 Maperitive 生成的图块上旋转标签
Rotate labels on tiles generated by Maperitive
我在 web 地图上使用自定义生成的图块(使用 openlayers 显示)。
瓷砖是由 maperetive 生成的,它很棒。但是,我的地图旋转了 -3/4Pi(openlayers 具有此功能)并且许多标签被颠倒了。
我相信 maperitive 没有相对于任意角度渲染标签的功能。可能还有其他方法可以解决这个问题?
也许你可以在 maperetive 中使用 export-bitmap 命令生成位图。然后你旋转整个。希望对您有所帮助!
我能够使用 dnSpy.
解决更改 Maperitive (v2.4.1) dll 的问题
标签的放置是通过Karta.MapLabeling.Igor2LineFeatureLabelPlacementAlgorithm.EvaluatePosition()
方法完成的(来自Karta.dll)。下面是修改后的方法。我在三个地方添加了 + 225f
。 225(度)等于 -3/4*Pi(弧度)。附加值应该是正的。
public static LabelPositionEvaluation EvaluatePosition(IPolylineAnalysis polylineAnalysis, float position, float? lengthAround)
{
if (lengthAround != null)
{
float? num = lengthAround;
if (num.GetValueOrDefault() <= 0f && num != null)
{
throw new ArgumentOutOfRangeException("lengthAround");
}
}
LabelPositionEvaluation labelPositionEvaluation = new LabelPositionEvaluation(position);
float polylineLength = polylineAnalysis.PolylineLength;
float num2 = (lengthAround != null) ? (position * polylineLength - lengthAround.Value) : 0f;
float num3 = (lengthAround != null) ? (position * polylineLength + lengthAround.Value) : (polylineLength * 0.9999f);
labelPositionEvaluation.Fits = (num2 >= 0f && num3 <= polylineLength);
if (!labelPositionEvaluation.Fits)
{
return labelPositionEvaluation;
}
IPolylineWalker polylineWalker = polylineAnalysis.CreateWalker();
polylineWalker.MoveTo(num2);
int currentSegment = polylineWalker.CurrentSegment;
float num4 = (polylineAnalysis.SegmentLengths[polylineWalker.CurrentSegment] - polylineWalker.CurrentOffsetWithinSegment) * polylineWalker.CurrentAngle;
polylineWalker.MoveTo(num3);
int currentSegment2 = polylineWalker.CurrentSegment;
if (currentSegment2 == currentSegment)
{
num4 = ((lengthAround != null) ? (polylineWalker.CurrentAngle * lengthAround.Value * 2f) : (polylineWalker.CurrentAngle * polylineLength));
}
else
{
num4 += polylineWalker.CurrentOffsetWithinSegment * polylineWalker.CurrentAngle;
}
float num5 = 0f;
for (int i = currentSegment; i < currentSegment2; i++)
{
float num6 = (float)GeometryUtils.DifferenceBetweenAngles((double)polylineAnalysis.SegmentAngles[i], (double)polylineAnalysis.SegmentAngles[i + 1], 360.0);
if (num6 > num5)
{
num5 = num6;
}
if (i > currentSegment)
{
num4 += polylineAnalysis.SegmentLengths[i] * polylineAnalysis.SegmentAngles[i];
}
}
labelPositionEvaluation.AverageAngle = (float)GeometryUtils.NormalizeAngle((double)((lengthAround != null) ? (num4 / (lengthAround.Value * 2f) + 225f) : (num4 / polylineLength + 225f)), 360.0);
labelPositionEvaluation.MaxCornerAngle = num5;
float angleForPosition = (float)GeometryUtils.NormalizeAngle((double)(polylineAnalysis.GetAngleForPosition(labelPositionEvaluation.Position) + 225f), 360.0);
labelPositionEvaluation.ForwardDirection = (angleForPosition < 90f || angleForPosition > 270f);
return labelPositionEvaluation;
}
我在 web 地图上使用自定义生成的图块(使用 openlayers 显示)。 瓷砖是由 maperetive 生成的,它很棒。但是,我的地图旋转了 -3/4Pi(openlayers 具有此功能)并且许多标签被颠倒了。 我相信 maperitive 没有相对于任意角度渲染标签的功能。可能还有其他方法可以解决这个问题?
也许你可以在 maperetive 中使用 export-bitmap 命令生成位图。然后你旋转整个。希望对您有所帮助!
我能够使用 dnSpy.
解决更改 Maperitive (v2.4.1) dll 的问题标签的放置是通过Karta.MapLabeling.Igor2LineFeatureLabelPlacementAlgorithm.EvaluatePosition()
方法完成的(来自Karta.dll)。下面是修改后的方法。我在三个地方添加了 + 225f
。 225(度)等于 -3/4*Pi(弧度)。附加值应该是正的。
public static LabelPositionEvaluation EvaluatePosition(IPolylineAnalysis polylineAnalysis, float position, float? lengthAround)
{
if (lengthAround != null)
{
float? num = lengthAround;
if (num.GetValueOrDefault() <= 0f && num != null)
{
throw new ArgumentOutOfRangeException("lengthAround");
}
}
LabelPositionEvaluation labelPositionEvaluation = new LabelPositionEvaluation(position);
float polylineLength = polylineAnalysis.PolylineLength;
float num2 = (lengthAround != null) ? (position * polylineLength - lengthAround.Value) : 0f;
float num3 = (lengthAround != null) ? (position * polylineLength + lengthAround.Value) : (polylineLength * 0.9999f);
labelPositionEvaluation.Fits = (num2 >= 0f && num3 <= polylineLength);
if (!labelPositionEvaluation.Fits)
{
return labelPositionEvaluation;
}
IPolylineWalker polylineWalker = polylineAnalysis.CreateWalker();
polylineWalker.MoveTo(num2);
int currentSegment = polylineWalker.CurrentSegment;
float num4 = (polylineAnalysis.SegmentLengths[polylineWalker.CurrentSegment] - polylineWalker.CurrentOffsetWithinSegment) * polylineWalker.CurrentAngle;
polylineWalker.MoveTo(num3);
int currentSegment2 = polylineWalker.CurrentSegment;
if (currentSegment2 == currentSegment)
{
num4 = ((lengthAround != null) ? (polylineWalker.CurrentAngle * lengthAround.Value * 2f) : (polylineWalker.CurrentAngle * polylineLength));
}
else
{
num4 += polylineWalker.CurrentOffsetWithinSegment * polylineWalker.CurrentAngle;
}
float num5 = 0f;
for (int i = currentSegment; i < currentSegment2; i++)
{
float num6 = (float)GeometryUtils.DifferenceBetweenAngles((double)polylineAnalysis.SegmentAngles[i], (double)polylineAnalysis.SegmentAngles[i + 1], 360.0);
if (num6 > num5)
{
num5 = num6;
}
if (i > currentSegment)
{
num4 += polylineAnalysis.SegmentLengths[i] * polylineAnalysis.SegmentAngles[i];
}
}
labelPositionEvaluation.AverageAngle = (float)GeometryUtils.NormalizeAngle((double)((lengthAround != null) ? (num4 / (lengthAround.Value * 2f) + 225f) : (num4 / polylineLength + 225f)), 360.0);
labelPositionEvaluation.MaxCornerAngle = num5;
float angleForPosition = (float)GeometryUtils.NormalizeAngle((double)(polylineAnalysis.GetAngleForPosition(labelPositionEvaluation.Position) + 225f), 360.0);
labelPositionEvaluation.ForwardDirection = (angleForPosition < 90f || angleForPosition > 270f);
return labelPositionEvaluation;
}