Пример #1
0
        /// <summary>
        /// Method to place the street direction symbols
        /// </summary>
        /// <param name="map"></param>
        /// <param name="lineString"></param>
        /// <param name="graphics"></param>
        private void OnRenderInternal(SharpMap.MapViewport map, GeoAPI.Geometries.ILineString lineString,
                                      System.Drawing.Graphics graphics)
        {
            var length = lineString.Length;
            var lil    = new NetTopologySuite.LinearReferencing.LengthIndexedLine(lineString);

            if (length < RepeatInterval + ArrowLength)
            {
                var start = System.Math.Max(0, (length - ArrowLength) / 2);
                var end   = System.Math.Min(length, (length + ArrowLength) / 2);
                var arrow = (GeoAPI.Geometries.ILineString)lil.ExtractLine(start, end);

                RenderArrow(map, graphics, arrow);

                return;
            }

            var numArrows = (int)((lineString.Length - ArrowLength) / RepeatInterval);
            var offset    = (lineString.Length - numArrows * RepeatInterval - ArrowLength) * 0.5;

            while (offset + ArrowLength < lineString.Length)
            {
                var arrow = (GeoAPI.Geometries.ILineString)lil.ExtractLine(offset, offset + ArrowLength);
                RenderArrow(map, graphics, arrow);
                offset += RepeatInterval;
            }
        }
Пример #2
0
    /// <summary>
    /// Method to place the street direction symbols
    /// </summary>
    /// <param name="map"></param>
    /// <param name="lineString"></param>
    /// <param name="graphics"></param>
    private void OnRenderInternal(SharpMap.Map map, GeoAPI.Geometries.ILineString lineString,
        System.Drawing.Graphics graphics)
    {

        var length = lineString.Length;
        var lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(lineString);
        if (length < RepeatInterval + ArrowLength)
        {
            var start = System.Math.Max(0, (length - ArrowLength)/2);
            var end = System.Math.Min(length, (length + ArrowLength)/2);
            var arrow = (GeoAPI.Geometries.ILineString) lil.ExtractLine(start, end);

            RenderArrow(map, graphics, arrow);

            return;
        }

        var numArrows = (int) ((lineString.Length - ArrowLength)/RepeatInterval);
        var offset = (lineString.Length - numArrows*RepeatInterval - ArrowLength)*0.5;

        while (offset + ArrowLength < lineString.Length)
        {
            var arrow = (GeoAPI.Geometries.ILineString) lil.ExtractLine(offset, offset + ArrowLength);
            RenderArrow(map, graphics, arrow);
            offset += RepeatInterval;
        }

    }
Пример #3
0
public SharpMap.Geometries.MultiLineString SplitLineString(
    SharpMap.Geometries.LineString lineString, 
    System.Double length)
{
    if (lineString == null || lineString.IsEmpty())
        throw new System.ArgumentException("Linestring is null or Empty", "lineString");

    var gf = new NetTopologySuite.Geometries.GeometryFactory();
    var ntsLine = (NetTopologySuite.Geometries.LineString)
                    SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(lineString, gf);

    var ret = new SharpMap.Geometries.MultiLineString();
    var lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(ntsLine);

    double currentLength = 0d;
    while (currentLength  < ntsLine.Length)
    {
        var tmpLine = (NetTopologySuite.Geometries.LineString)
            lil.ExtractLine(currentLength, currentLength + length);
        ret.LineStrings.Add((SharpMap.Geometries.LineString)
            SharpMap.Converters.NTS.GeometryConverter.ToSharpMapGeometry(tmpLine));
        currentLength += length;
    }
    return ret;
}
Пример #4
0
        public GeoAPI.Geometries.IMultiLineString SplitLineString(
            GeoAPI.Geometries.ILineString lineString,
            System.Double length)
        {
            if (lineString == null || lineString.IsEmpty)
            {
                throw new System.ArgumentException("Linestring is null or Empty", "lineString");
            }

            //var gf = new NetTopologySuite.Geometries.GeometryFactory();
            //var ntsLine = (NetTopologySuite.Geometries.LineString)
            //                SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(lineString, gf);

            var ret = new System.Collections.Generic.List <GeoAPI.Geometries.ILineString>();
            var lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(lineString);

            double currentLength = 0d;

            while (currentLength < lineString.Length)
            {
                var tmpLine = (GeoAPI.Geometries.ILineString)
                              lil.ExtractLine(currentLength, currentLength + length);
                ret.Add(tmpLine);
                currentLength += length;
            }
            return(lineString.Factory.CreateMultiLineString(ret.ToArray()));
        }
Пример #5
0
        public SharpMap.Geometries.MultiLineString SplitLineString(
            SharpMap.Geometries.LineString lineString,
            System.Double length)
        {
            if (lineString == null || lineString.IsEmpty())
            {
                throw new System.ArgumentException("Linestring is null or Empty", "lineString");
            }

            var gf      = new NetTopologySuite.Geometries.GeometryFactory();
            var ntsLine = (NetTopologySuite.Geometries.LineString)
                          SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(lineString, gf);

            var ret = new SharpMap.Geometries.MultiLineString();
            var lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(ntsLine);

            double currentLength = 0d;

            while (currentLength < ntsLine.Length)
            {
                var tmpLine = (NetTopologySuite.Geometries.LineString)
                              lil.ExtractLine(currentLength, currentLength + length);
                ret.LineStrings.Add((SharpMap.Geometries.LineString)
                                    SharpMap.Converters.NTS.GeometryConverter.ToSharpMapGeometry(tmpLine));
                currentLength += length;
            }
            return(ret);
        }
public GeoAPI.Geometries.IMultiLineString SplitLineString(
    GeoAPI.Geometries.ILineString lineString, 
    System.Double length)
{
    if (lineString == null || lineString.IsEmpty)
        throw new System.ArgumentException("Linestring is null or Empty", "lineString");

    //var gf = new NetTopologySuite.Geometries.GeometryFactory();
    //var ntsLine = (NetTopologySuite.Geometries.LineString)
    //                SharpMap.Converters.NTS.GeometryConverter.ToNTSGeometry(lineString, gf);

    var ret = new System.Collections.Generic.List<GeoAPI.Geometries.ILineString>();
    var lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(lineString);

    double currentLength = 0d;
    while (currentLength  < lineString.Length)
    {
        var tmpLine = (GeoAPI.Geometries.ILineString)
            lil.ExtractLine(currentLength, currentLength + length);
        ret.Add(tmpLine);
        currentLength += length;
    }
    return lineString.Factory.CreateMultiLineString(ret.ToArray());
}
Пример #7
0
        private static BaseLabel CreatePathLabel(ILineString line, string text, SizeF textMeasure,
                                                 int priority, LabelStyle style, MapViewport map)
        {
            if (line == null)
            {
                return(null);
            }

            var factory = line.Factory;

            // Simplify the line for smoother labeling
            double avgCharacterSpace = 2d * textMeasure.Width / text.Length * map.PixelWidth;
            var    simplifier        = new NetTopologySuite.Simplify.VWLineSimplifier(line.Coordinates, avgCharacterSpace);

            line = factory.CreateLineString(simplifier.Simplify());

            var labelLength = textMeasure.Width * map.PixelWidth;
            var labelHeight = textMeasure.Height * map.PixelHeight;

            var offsetX = style.Offset.X * map.PixelWidth;  // positive = increasing measure
            var offsetY = style.Offset.Y * map.PixelHeight; // positive = right side of line

            var start = 0d;

            if (style.HorizontalAlignment == LabelStyle.HorizontalAlignmentEnum.Center)
            {
                start = line.Length * 0.5 - labelLength * 0.5;
            }
            else if (style.HorizontalAlignment == LabelStyle.HorizontalAlignmentEnum.Right)
            {
                start = line.Length - labelLength;
            }

            start += offsetX;

            // Constrain label length
            if (labelLength > 0.95 * line.Length && !style.IgnoreLength ||
                start + labelLength < 0 || start > line.Length)
            {
                return(null);
            }

            // LengthIndexedLine idea courtesy FObermaier
            NetTopologySuite.LinearReferencing.LengthIndexedLine lil;

            // optimize for detailed lines (eg labelling rivers at continental level)
            // ratio and NumPoints based on instinct.... feel free to revise
            var mid = start + labelLength / 2.0;

            if (labelLength / line.Length < 0.5 && line.NumPoints > 200 && mid >= 0 && mid < line.Length)
            {
                lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(line);
                var midPt = lil.ExtractPoint(mid);
                // extract slightly more than label length to ensure offsetCurve follows line geometry
                var halfLen = labelLength * 0.6;
                // ensure non-negative indexes constrained to line length (due to special LengthIndexLine functionality)
                line = (LineString)lil.ExtractLine(Math.Max(0, mid - halfLen), Math.Min(mid + halfLen, line.Length));
                // reset start
                lil   = new NetTopologySuite.LinearReferencing.LengthIndexedLine(line);
                mid   = lil.IndexOf(midPt);
                start = mid - labelLength / 2.0;
            }

            // basic extend
            var end = start + labelLength;

            if (start < 0 || end > line.Length)
            {
                line = ExtendLine(line,
                                  start <0 ? -1 * start : 0,
                                         end> line.Length ? end - line.Length : 0);
                start = 0;
                end   = start + labelLength;
            }

            lil = new NetTopologySuite.LinearReferencing.LengthIndexedLine(line);
            // reverse
            var startPt = lil.ExtractPoint(start);
            var endPt   = lil.ExtractPoint(end);

            if (LineNeedsReversing(startPt, endPt, false, map))
            {
                start = end;
                end   = start - labelLength;
            }
            line = (ILineString)lil.ExtractLine(start, end);

            // Build offset curve
            ILineString offsetCurve;
            var         bufferParameters =
                new NetTopologySuite.Operation.Buffer.BufferParameters(4,
                                                                       GeoAPI.Operation.Buffer.EndCapStyle.Flat);

            // determine offset curve that will run through the vertical centre of the text
            if (style.VerticalAlignment != LabelStyle.VerticalAlignmentEnum.Middle)
            {
                var ocb = new NetTopologySuite.Operation.Buffer.OffsetCurveBuilder(factory.PrecisionModel,
                                                                                   bufferParameters);

                // Left side positive
                var offsetCurvePoints = ocb.GetOffsetCurve(line.Coordinates,
                                                           ((int)style.VerticalAlignment - 1) * 0.5 * labelHeight - offsetY);
                offsetCurve = factory.CreateLineString(offsetCurvePoints);
            }
            else
            {
                offsetCurve = line;
            }

            // basic extend
            var ratio = labelLength / offsetCurve.Length;

            if (ratio > 1.01)
            {
                var diff = labelLength - offsetCurve.Length;
                offsetCurve = ExtendLine(offsetCurve, diff / 2d, diff / 2d);
            }

            // enclosing polygon in world coords
            var affectedArea = (IPolygon)offsetCurve.Buffer(0.5d * labelHeight, bufferParameters);

            // fast, basic check (technically should use polygons for rotated views)
            if (!map.Envelope.Contains(affectedArea.EnvelopeInternal))
            {
                return(null);
            }

            // using labelBox to pass text height to WarpedPath
            return(new PathLabel(text, LineStringToPath(offsetCurve, map), 0, priority,
                                 new LabelBox(0, 0, textMeasure.Width, textMeasure.Height), style)
            {
                AffectedArea = affectedArea
            });
        }
Пример #8
0
        private void RenderLineLabel(TextSymbolizer textSymbolizer, Feature feature)
        {
            //TODO labels could be not strings
            var str = feature.Attributes.Exists(textSymbolizer.LabelAttribute) ? feature.Attributes[textSymbolizer.LabelAttribute] as string : null;

            if (string.IsNullOrWhiteSpace(str))
            {
                return;
            }

            var emSize = Graphics.DpiY * textSymbolizer.FontSize / 72;

            //ref http://msdn.microsoft.com/en-us/library/xwf9s90b(v=vs.110).aspx
            var font   = FontCache[textSymbolizer];
            var ascent = emSize * font.FontFamily.GetCellAscent(FontStyle.Bold) / font.FontFamily.GetEmHeight(FontStyle.Bold);

            Graphics.SmoothingMode = SmoothingMode.HighQuality;

            var   size    = Graphics.MeasureString(str, font);
            float spacing = textSymbolizer.Spacing;

            var coords        = ProjectToCoordinate(feature.Geometry.Coordinates);
            var coordsAsLine  = new LineString(coords);
            var lengthIndexed = new NetTopologySuite.LinearReferencing.LengthIndexedLine(coordsAsLine);

            var labelCount = (int)((coordsAsLine.Length - spacing) / (size.Width + spacing));

            if (labelCount < 1 || textSymbolizer.Spacing == 0)
            {
                labelCount = 1;
            }

            //work out spacing based on the amount of labels we'll be putting on
            spacing = ((float)coordsAsLine.Length / labelCount) - size.Width;

            for (var i = 0; i < labelCount; i++)
            {
                var labelCenterLength = (spacing + size.Width) * (0.5f + i);
                var subLine           = lengthIndexed.ExtractLine(labelCenterLength - (size.Width / 2), labelCenterLength + (size.Width / 2));
                if (subLine.Coordinates.Length < 2)
                {
                    continue;
                }

                var firstCoord             = subLine.Coordinates[0];
                var lastCoord              = subLine.Coordinates[subLine.Coordinates.Length - 1];
                var middleOfLabelLinePoint = lengthIndexed.ExtractPoint(labelCenterLength);


                var midPoint = new PointF((float)(firstCoord.X + lastCoord.X + middleOfLabelLinePoint.X + middleOfLabelLinePoint.X) * 0.25f, (float)(firstCoord.Y + lastCoord.Y + middleOfLabelLinePoint.Y + middleOfLabelLinePoint.Y) * 0.25f);

                var angle = (float)(Math.Atan2(lastCoord.Y - firstCoord.Y, lastCoord.X - firstCoord.X) * 180 / Math.PI);
                //Keep the text up the right way
                while (angle + Config.Angle > 90)
                {
                    angle -= 180;
                }
                while (angle + Config.Angle < -90)
                {
                    angle += 180;
                }

                TryRenderText(textSymbolizer, feature, emSize, str, midPoint, SizeF.Empty, new SizeF(size.Width, ascent), angle);
            }
        }