在 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;
        }