1

I'm using custom generated tiles on web map (displayed using openlayers). Tiles are generated by maperetive and it's great. However my map is rotated -3/4Pi (openlayers has this feature) and many labels are rendered upside down. I belive maperitive has no feature to render labels relative to arbitrary angle. May be there are other options to fix this?

Example of rotated label

ambienthack
  • 380
  • 4
  • 8
  • 1
    Try re-asking this question at http://gis.stackexchange.com or http://help.openstreetmap.org/. – scai Feb 06 '17 at 08:24

2 Answers2

0

Maybe you can generate bitmap using export-bitmap command in maperetive. Then you rotate the whole. Hope this help!

slou
  • 34
  • 6
0

I was able to solve the problem (to some degree) altering dll's of Maperitive using ILSpy & Reflexil.

If someone is interested, rendering of labels is done by GdiPainter.DrawText(string, IPointF2List, ...) method (from Karta.dll). It uses Brejc.Geometry.Algorithms.Polylines.Analysis.PolylineWalker class (from Brejc.Geospatial.dll), which controls placement of individual characters across polyline. I altered this class to make it walk along the polyline in the opposite direction.

public class PolylineWalker : IPolylineWalker
{
    private readonly PolylineAnalysis polylineAnalysis;

    private float currentOffset;

    private int currentSegment;

    private float currentOffsetWithinSegment;

    private float polylineLength;

    public float CurrentAngle
    {
        get
        {
            return this.polylineAnalysis.SegmentAngles[this.currentSegment] + 180f;
        }
    }

    public float CurrentOffsetWithinSegment
    {
        get
        {
            return this.currentOffsetWithinSegment;
        }
    }

    public Brejc.Geometry.PointF2 CurrentPoint
    {
        get
        {
            float num;
            float num2;
            this.polylineAnalysis.Points.GetPoint(this.currentSegment, out num, out num2);
            float num3;
            float num4;
            this.polylineAnalysis.Points.GetPoint(this.currentSegment + 1, out num3, out num4);
            float num5 = this.currentOffsetWithinSegment / this.polylineAnalysis.SegmentLengths[this.currentSegment];
            float x = (num - num3) * num5 + num3;
            float y = (num2 - num4) * num5 + num4;
            return new Brejc.Geometry.PointF2(x, y);
        }
    }

    public float CurrentOffset
    {
        get
        {
            return this.currentOffset;
        }
    }

    public int CurrentSegment
    {
        get
        {
            return this.currentSegment;
        }
    }

    public float LengthLeftOnSegment
    {
        get
        {
            return this.polylineAnalysis.SegmentLengths[this.currentSegment] - this.currentOffsetWithinSegment;
        }
    }

    public PolylineWalker(PolylineAnalysis polylineAnalysis)
    {
        this.polylineAnalysis = polylineAnalysis;
        this.polylineLength = polylineAnalysis.PolylineLength;
    }

    public void MoveBy(float delta)
    {
        if (delta.IsZero())
        {
            return;
        }
        if (this.currentOffset + delta > this.polylineLength)
        {
            throw new System.ArgumentOutOfRangeException("delta");
        }
        if (this.currentOffset + delta == this.polylineLength)
        {
            int num = 0;
            num++;
        }
        float num2 = this.currentOffset + delta;
        this.currentOffset -= this.currentOffsetWithinSegment;
        if (delta > 0f)
        {
            while (this.currentSegment >= 0)
            {
                this.currentOffset += this.polylineAnalysis.SegmentLengths[this.currentSegment];
                if (this.currentOffset >= num2)
                {
                    this.currentOffsetWithinSegment = num2 - (this.currentOffset - this.polylineAnalysis.SegmentLengths[this.currentSegment]);
                    this.currentOffset = num2;
                    return;
                }
                this.currentSegment--;
            }
            throw new System.InvalidOperationException("Bug in the algorithm");
        }
        this.MoveTo(num2);
    }

    public void MoveTo(float offset)
    {
        if (offset < 0f)
        {
            throw new System.ArgumentOutOfRangeException("offset");
        }
        if (offset > this.polylineLength)
        {
            throw new System.ArgumentOutOfRangeException("offset");
        }
        this.currentOffset = 0f;
        this.currentSegment = this.polylineAnalysis.SegmentsCount - 1;
        while (this.currentSegment >= 0)
        {
            if (this.currentOffset + this.polylineAnalysis.SegmentLengths[this.currentSegment] >= offset)
            {
                this.currentOffsetWithinSegment = offset - this.currentOffset;
                this.currentOffset = offset;
                return;
            }
            this.currentOffset += this.polylineAnalysis.SegmentLengths[this.currentSegment];
            this.currentSegment--;
        }
        throw new System.InvalidOperationException("Bug in the algorithm");
    }
}
ambienthack
  • 380
  • 4
  • 8