Ejemplo n.º 1
0
        public ManualObject CreateNode(string name, SceneManager sceneMgr, bool isClosed)
        {
            if (lineNode == null)
            {
                lineNode = sceneMgr.CreateManualObject(name);
                MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourPolygon",
                                                                        ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                material.GetTechnique(0).GetPass(0).VertexColourTracking =
                    (int)TrackVertexColourEnum.TVC_AMBIENT;

                int nSeg = 5; // Number of segments on the cap or join pieces
                BufferParameters param       = new BufferParameters(nSeg, BufferParameters.BufferEndCapStyle.CapRound, BufferParameters.BufferJoinStyle.JoinRound, 2);
                IGeometry        coordBuffer = line1.Buffer(0.5, param);

                Tesselate(coordBuffer.Coordinates);
            }
            return(lineNode);
        }
Ejemplo n.º 2
0
        // FragmentFilter overrides
        public override FragmentList process(FeatureList input, FilterEnv env)
        {
            FragmentList output = new FragmentList();

            //cuidado con las entidades dentro del for

            int     i = 0;
            Vector3 scale;
            Vector3 distanceScale;
            Vector3 mScale = new Vector3(1, 1, 1);
            float   lWidth = 1;

            if (Scale != null)
            {
                scale = Registry.instance().GetEngine("Python").run(Scale).asVec3();
            }
            else
            {
                scale = new Vector3(1, 1, 1);
            }

            if (CoordScale != null)
            {
                distanceScale = Registry.instance().GetEngine("Python").run(CoordScale).asVec3();
            }
            else
            {
                distanceScale = new Vector3(1, 1, 1);
            }
            if (LineWidth != null)
            {
                lWidth = Registry.instance().GetEngine("Python").run(LineWidth).asFloat();
            }
            if (MaterialScale != null)
            {
                mScale = Registry.instance().GetEngine("Python").run(MaterialScale).asVec3();
            }

            SceneNode nodeIni = point3d(env.getName(), i, 0, 0, 0, null, env.getSceneMgr());

#if ESCALA_NODO_INICIAL
            if (Scale != null)
            {
                nodeIni.SetScale(Registry.instance().GetEngine("Python").run(Scale).asVec3());
            }
            if (coordScale != null)
            {
                Vector3 vec3 = Registry.instance().GetEngine("Python").run(Scale).asVec3();
                nodeIni.SetPosition(nodeIni.Position.x * vec3.x, nodeIni.Position.y * vec3.y, nodeIni.Position.z * vec3.z);
#if TRACE_BUILDGEOMFILTER
                System.Console.WriteLine("(" + n.Position.x + "," + n.Position.y + ")");
#endif
            }
#endif
            Fragment fIni = new Fragment(nodeIni);
            output.Add(fIni);

            foreach (Feature feature in input)
            {
                //if type of features is Point
                if (feature.row.Geometry is SharpMap.Geometries.Point)
                {
                    SharpMap.Geometries.Point p = (SharpMap.Geometries.Point)feature.row.Geometry;

                    i++;
                    SceneNode n = point3d(env.getName(), i, (float)p.X, (float)p.Y, 0, nodeIni, env.getSceneMgr());

                    n.SetScale(scale);
                    n.SetPosition(n.Position.x * distanceScale.x, n.Position.y * distanceScale.y, n.Position.z * distanceScale.z);

                    Fragment f = new Fragment(n);
                    output.Add(f);
                }

                //if type of features is Polygon
                else if (feature.row.Geometry is SharpMap.Geometries.Polygon)
                {
                    SharpMap.Geometries.Polygon polygon = (SharpMap.Geometries.Polygon)feature.row.Geometry;

                    ManualObject polygonNode = null;

                    if (polygonNode == null)
                    {
                        polygonNode = env.getSceneMgr().CreateManualObject(env.getName() + "Node_" + i);
                        MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourPolygon",
                                                                                ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                        material.GetTechnique(0).GetPass(0).VertexColourTracking =
                            (int)TrackVertexColourEnum.TVC_AMBIENT;

                        //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                        MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygonNode, Color, feature);

                        if (nameMaterial != null)
                        {
                            callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                            callback.MaterialScale = mScale;
                        }

                        GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                        Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                        Glu.gluTessBeginPolygon(null);
                        Glu.gluTessBeginContour();

                        int        numVertices = polygon.ExteriorRing.NumPoints /*/10+1*/;
                        int        numValores  = 3;
                        double[][] data        = new double[numVertices][];

                        for (int j = 0; j < numVertices; j++)
                        {
                            data[j] = new double[numValores];
                        }

                        int k = 0;
                        //1 polygon = N vertices
                        foreach (SharpMap.Geometries.Point point in polygon.ExteriorRing.Vertices)
                        {
                            //if (k % 10 == 0)
                            {
                                data[k /*/10*/][0] = point.X;
                                data[k /*/10*/][1] = point.Y;
                                data[k /*/10*/][2] = 0;
                            }
                            k++;

                            //SceneNode n = point3d(env.getName()+i+k, k + 10, (float)point.X * 10.0f, (float)point.Y * 10.0f, 0, nodeIni, env.getSceneMgr());
                        }
                        for (int j = 0; j < data.GetLength(0); j++)
                        {
                            Glu.gluTessVertex(data[j], 0, new Vector3((float)(data[j][1] * distanceScale.y), (float)(data[j][2] * distanceScale.z), (float)(data[j][0] * distanceScale.x)));
                        }

                        Glu.gluTessEndContour();
                        Glu.gluTessNormal(0, 0, 1);
                        Glu.gluTessEndPolygon();

                        nodeIni.AttachObject(polygonNode);
                    }
                    i++;
                }

                //if type of features is MultiPolygon
                else if (feature.row.Geometry is SharpMap.Geometries.MultiPolygon)
                {
                    SharpMap.Geometries.MultiPolygon mp = (SharpMap.Geometries.MultiPolygon)feature.row.Geometry;

                    // 1 MultiPolygon = N polygon
                    foreach (SharpMap.Geometries.Polygon polygon in mp.Polygons)
                    {
                        ManualObject polygonNode = null;

                        if (polygonNode == null)
                        {
                            polygonNode = env.getSceneMgr().CreateManualObject(env.getName() + "Node_" + i);
                            MaterialPtr material = MaterialManager.Singleton.Create("Test/ColourPolygon",
                                                                                    ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                            material.GetTechnique(0).GetPass(0).VertexColourTracking =
                                (int)TrackVertexColourEnum.TVC_AMBIENT;


                            //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                            MogreTessellationCallbacks callback = new MogreTessellationCallbacks(polygonNode, Color, feature);

                            if (nameMaterial != null)
                            {
                                callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                                callback.MaterialScale = mScale;
                            }

                            GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                            Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                            Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                            Glu.gluTessBeginPolygon(null);
                            Glu.gluTessBeginContour();

                            int        numVertices = polygon.ExteriorRing.NumPoints;
                            int        numValores  = 3;
                            double[][] data        = new double[numVertices][];

                            for (int j = 0; j < numVertices; j++)
                            {
                                data[j] = new double[numValores];
                            }

                            int k = 0;
                            //1 polygon = N vertices
                            foreach (SharpMap.Geometries.Point point in polygon.ExteriorRing.Vertices)
                            {
                                data[k][0] = point.X;
                                data[k][1] = point.Y;
                                data[k][2] = 0;

                                k++;

                                //SceneNode n = point3d(env.getName(), i, (float)point.X, (float)point.Y, 0, nodeIni, env.getSceneMgr());
                            }
                            for (int j = 0; j < data.GetLength(0); j++)
                            {
                                Glu.gluTessVertex(data[j], 0, new Vector3(((float)data[j][1]) * distanceScale.y, ((float)data[j][2]) * distanceScale.z, ((float)data[j][0]) * distanceScale.x));
                            }

                            Glu.gluTessEndContour();
                            Glu.gluTessNormal(0, 0, 1);
                            Glu.gluTessEndPolygon();

                            nodeIni.AttachObject(polygonNode);
                        }
                        i++;
                    }
                }

                //if type of features is Line
                else if (feature.row.Geometry is SharpMap.Geometries.ILineal /*SharpMap.Geometries.LineString*/)
                {
                    System.Collections.Generic.List <SharpMap.Geometries.ILineal> lineas = new System.Collections.Generic.List <SharpMap.Geometries.ILineal>();
                    if (feature.row.Geometry is SharpMap.Geometries.MultiLineString)
                    {
                        foreach (SharpMap.Geometries.LineString l in ((SharpMap.Geometries.MultiLineString)(feature.row.Geometry)).LineStrings)
                        {
                            lineas.Add(l);
                        }
                    }
                    else
                    {
                        lineas.Add((SharpMap.Geometries.ILineal)(feature.row.Geometry));
                    }
                    foreach (SharpMap.Geometries.ILineal line in lineas)
                    {
                        ManualObject lineNode = env.getSceneMgr().CreateManualObject("line" + i);

                        //MaterialPtr material = MaterialManager.Singleton.Create(nameMaterial,
                        //ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME);
                        //material.GetTechnique(0).GetPass(0).VertexColourTracking =
                        //               (int)TrackVertexColourEnum.TVC_AMBIENT;
                        //material.GetTechnique(0).GetPass(0).SetDepthBias(100);
                        //material.GetTechnique(0).GetPass(0).LightingEnabled = false;

                        int nSeg = 5; // Number of segments on the cap or join pieces
                        BufferParameters         param           = new BufferParameters(nSeg, BufferParameters.BufferEndCapStyle.CapRound, BufferParameters.BufferJoinStyle.JoinRound, 2);
                        IGeometryFactory <Coord> geometryFactory = new GeometryFactory <Coord>(new CoordSeqFac(new CoordFac(PrecisionModelType.DoubleFloating)));
                        //IWktGeometryReader<Coord> reader = geometryFactory.WktReader;
                        //string txt = feature.row.Geometry.AsText();
                        ILineString         line1       = (ILineString)GeometryConverter.ToNTSGeometry((SharpMap.Geometries.LineString)line, geometryFactory); // (ILineString<Coord>)reader.Read(txt);
                        IGeometry           coordBuffer = line1.Buffer(lWidth, param);
                        ICoordinateSequence coords      = coordBuffer.Coordinates;
                        //Vector3 v = Registry.instance().GetEngine("Python").run(Color, feature, null).asVec3();
                        MogreTessellationCallbacks callback = new MogreTessellationCallbacks(lineNode, Color, feature);
                        if (nameMaterial != null)
                        {
                            callback.Material      = nameMaterial; // "Test/ColourPolygon2";
                            callback.MaterialScale = mScale;
                        }

                        GLUtessellatorImpl Glu = (GLUtessellatorImpl)GLUtessellatorImpl.gluNewTess();
                        Glu.gluTessCallback(GLU.GLU_TESS_VERTEX, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_BEGIN, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_END, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_ERROR, callback);
                        Glu.gluTessCallback(GLU.GLU_TESS_COMBINE, callback);
                        Glu.gluTessBeginPolygon(null);
                        Glu.gluTessBeginContour();
                        foreach (Coord coord in coords)
                        {
                            double[] data = new double[] { coord.X *distanceScale.x, coord.Y *distanceScale.y, (double.IsNaN(coord.Z) ? 0 : coord.Z) * distanceScale.z };

                            Glu.gluTessVertex(data, 0, new Vector3((float)data[1], (float)data[2], (float)data[0]));
                        }
                        Glu.gluTessEndContour();
                        Glu.gluTessNormal(0, 0, 1);
                        Glu.gluTessEndPolygon();
                        i++;
                        nodeIni.AttachObject(lineNode);
                    }
                    if ((feature.row.Geometry is SharpMap.Geometries.Polygon) | (feature.row.Geometry is SharpMap.Geometries.MultiPolygon))
                    {
                        Fragment f = new Fragment(nodeIni);
                        output.Add(f);
                    }
                }
            }
            i = 0;//breakpoint

            /*foreach (Fragment fragment in output)
             * {
             *  fragment.Node.Scale(0,0,0);
             * }*/

#if TODO
            // if features are arriving in batch, resolve the color here.
            // otherwise we will resolve it later in process(feature,env).
            is_batch            = input.Count > 1;
            batch_feature_color = overall_color;
            if (is_batch && getColorScript() != null)
            {
                ScriptResult r = env.getScriptEngine().run(getColorScript(), env);
                if (r.isValid())
                {
                    batch_feature_color = r.asVec4();
                }
                else
                {
                    env.getReport().error(r.asString());
                }
            }

            return(base.process(input, env));
#endif
            //throw new NotImplementedException();

            if (successor != null)
            {
                if (successor is FeatureFilter)
                {
                    FeatureFilter filter = (FeatureFilter)successor;
                    FeatureList   l      = filter.process(input, env);
                    //FeatureList l = successor.process(input, env);
                }
                else if (successor is FragmentFilter)
                {
                    FragmentFilter filter = (FragmentFilter)successor;
                    FragmentList   l      = filter.process(output, env);
                }
            }

            return(output);
        }
        /// <summary>
        ///
        /// </summary>
        public override void Start()
        {
            IPoint      pointInLine  = Factory.CreatePoint(new Coordinate(20, 10));
            IPoint      pointOutLine = Factory.CreatePoint(new Coordinate(20, 31));
            ILineString aLine        = Factory.CreateLineString(new Coordinate[] { new Coordinate(23, 32.2), new Coordinate(922, 11) });
            ILineString anotherLine  = Factory.CreateLineString(new Coordinate[] { new Coordinate(0, 1), new Coordinate(30, 30) });

            try
            {
                Write(line.Area);
                Write(line.Boundary);
                Write(line.BoundaryDimension);
                Write(line.Centroid);
                Write(line.Coordinate);
                Write(line.Coordinates);
                Write(line.CoordinateSequence);
                Write(line.Dimension);
                Write(line.EndPoint);
                Write(line.Envelope);
                Write(line.EnvelopeInternal);
                Write(line.InteriorPoint);
                Write(line.IsClosed);
                Write(line.IsEmpty);
                Write(line.IsRing);
                Write(line.IsSimple);
                Write(line.IsValid);
                Write(line.Length);
                Write(line.NumPoints);
                Write(line.StartPoint);
                if (line.UserData != null)
                {
                    Write(line.UserData);
                }
                else
                {
                    Write("UserData null");
                }

                Write(line.Buffer(10));
                Write(line.Buffer(10, BufferStyle.CapButt));
                Write(line.Buffer(10, BufferStyle.CapSquare));
                Write(line.Buffer(10, 20));
                Write(line.Buffer(10, 20, BufferStyle.CapButt));
                Write(line.Buffer(10, 20, BufferStyle.CapSquare));
                Write(line.Contains(pointInLine));
                Write(line.Contains(pointOutLine));
                Write(line.Crosses(pointInLine));
                Write(line.Crosses(pointOutLine));
                Write(line.Difference(pointInLine));
                Write(line.Difference(pointOutLine));
                Write(line.Disjoint(pointInLine));
                Write(line.Disjoint(pointOutLine));
                Write(line.Distance(pointInLine));
                Write(line.Distance(pointOutLine));
                Write(line.Equals(line.Clone() as LineString));
                Write(line.EqualsExact(line.Clone() as LineString));
                Write(line.ConvexHull());
                Write(line.Intersection(pointInLine));
                Write(line.Intersection(pointOutLine));
                Write(line.Intersection(aLine));
                Write(line.Intersects(pointInLine));
                Write(line.Intersects(pointOutLine));
                Write(line.Intersects(aLine));
                Write(line.IsWithinDistance(pointOutLine, 2));
                Write(line.IsWithinDistance(pointOutLine, 222));
                Write(line.Overlaps(pointInLine));
                Write(line.Overlaps(pointOutLine));
                Write(line.Overlaps(aLine));
                Write(line.Overlaps(anotherLine));
                Write(line.Relate(pointInLine));
                Write(line.Relate(pointOutLine));
                Write(line.Relate(aLine));
                Write(line.Relate(anotherLine));
                Write(line.SymmetricDifference(pointInLine));
                Write(line.SymmetricDifference(pointOutLine));
                Write(line.SymmetricDifference(aLine));
                Write(line.SymmetricDifference(anotherLine));
                Write(line.ToString());
                Write(line.AsText());
                Write(line.Touches(pointInLine));
                Write(line.Touches(pointOutLine));
                Write(line.Touches(aLine));
                Write(line.Touches(anotherLine));
                Write(line.Union(pointInLine));
                Write(line.Union(pointOutLine));
                Write(line.Union(aLine));
                Write(line.Union(anotherLine));
                Write(line.Within(pointInLine));
                Write(line.Within(pointOutLine));
                Write(line.Within(aLine));
                Write(line.Within(anotherLine));

                string    linestring         = "LINESTRING (1.2 3.4, 5.6 7.8, 9.1 10.12)";
                string    anotherlinestringg = "LINESTRING (12345 3654321, 685 7777.945677, 782 111.1)";
                IGeometry geom1 = Reader.Read(linestring);
                Write(geom1.AsText());
                IGeometry geom2 = Reader.Read(anotherlinestringg);
                Write(geom2.AsText());

                byte[]    bytes = line.AsBinary();
                IGeometry test1 = new WKBReader().Read(bytes);
                Write(test1.ToString());

                bytes = new GDBWriter().Write(line);
                test1 = new GDBReader().Read(bytes);
                Write(test1.ToString());
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }
Ejemplo n.º 4
0
        /**
         * erzeugt eine Offset-Linie mit Hilfe von der buffer(offset) Funktion
         *
         * @param gf
         * @param baseline
         * @param offset ... rechts < 0, links > 0
         * @return
         * @throws VipDatabaseException
         */
        public static ILineString createOffsetLineNew(IGeometryFactory gf, ILineString baseline, double offset)
        {
            // 1.Schritt: Buffer bilden
            double    offsetAbs = Math.Abs(offset);
            IGeometry buffer;

            {
                // prüfen, ob eine Berechung nötig/möglich ist
                if (offsetAbs < THIN)
                {
                    return(baseline);
                }
                if (!baseline.IsSimple)
                {                                                    // sich kreuzende Linie aufteilen
                    return(partialOffsetLine(gf, baseline, offset)); // aufteilen und für beiden Teilen versuchen
                }

                buffer = baseline.Buffer(offsetAbs, 12, EndCapStyle.Flat);
                if (buffer == null)
                {
                    return(null);
                }
                if (buffer.IsEmpty)
                {
                    return(baseline);
                }
                if (buffer is MultiPolygon || // wegen JTS Bug: bufer kann manchmal MultiPolygon sein (siehe Nasenweg mit distance=5
                    (buffer is Polygon && ((Polygon)buffer).NumInteriorRings > 0))
                {                                                    // buffer hat Loch
                    return(partialOffsetLine(gf, baseline, offset)); // aufteilen und für beiden Teilen versuchen
                }
            }
            Coordinate[] baseCoords = baseline.Coordinates;

            // 2.Schritt: aus der Bufferlinie die Segmente entfernen, die zu nah zu der Basislinie sind
            IGeometry bufferLine = buffer.Boundary;
            {
                //      double minDist = Math.abs(offset) * 0.5;  // Segmente der Bufferlinie die zur baseline näher sind als minDist, werden entfernt
                List <Coordinate> bufferCoords = buffer.Coordinates.ToList();
                for (int i = 0; i < bufferCoords.Count - 1; i++)
                {
                    LineSegment segm     = new LineSegment(bufferCoords.ElementAt(i), bufferCoords.ElementAt(i + 1));
                    ILineString segmLine = gf.CreateLineString(new Coordinate[] { segm.P0, segm.P1 });

                    LineSegment segmBeg = createRectangle(gf, baseCoords[0], baseCoords[1], offsetAbs);                                         // Segment quer zur Anfang des Basislinie-Segments
                    LineSegment segmEnd = createRectangle(gf, baseCoords[baseCoords.Length - 1], baseCoords[baseCoords.Length - 2], offsetAbs); // Segment quer zur Anfang des Basislinie-Segments
                    if (contains(segmBeg, segm, THIN) || contains(segmEnd, segm, THIN))
                    {
                        bufferLine = bufferLine.Difference(segmLine); // Segment liegt auf einem Quer-Segment des Basislinien-Segments
                    }
                }
            }
            // 3.Schritt: die Bufferlinie sollte aus 2 Teilen bestehen (die 2 Offsetlinien)

            List <ILineString> lines = new List <ILineString>();
            {
                if (bufferLine is MultiLineString)
                {
                    lines = linesFromMultiLine(gf, (MultiLineString)bufferLine);
                }
                else if (bufferLine is LineString)
                {
                    lines.Add((LineString)bufferLine);
                }
                else
                {
                    return(partialOffsetLine(gf, baseline, offset));  // aufteilen und für beiden Teilen versuchen
                }
            }

            // 4. Schritt: jene Linie ist die Offsetlinie die ein Segment hat,
            //   das auf dem Offset eines Anfang/Endsegments der Basisline ist
            ILineString line = null;

            {
                double sumDistMin = Double.MaxValue;

                foreach (ILineString linePart in lines)
                {                       // die beste Linie auswählen
                    double sumDist = 0; // Summe Entfernung der Offset-Segmenten der Basislinie von der linePart
                    for (int i = 1; i < baseCoords.Length; i++)
                    {
                        LineSegment segm          = new LineSegment(baseCoords[i - 1], baseCoords[i]);
                        LineSegment segmentOffset = createSegmentOffset(segm, offset);
                        if (i == 1 || i == baseCoords.Count() - 1)
                        {                              // Anfang- oder Endsegment
                            if (segmOnLine(segmentOffset, linePart))
                            {                          // ein Segment der LInie linePart liegt auf dem segmentOffset
                                line       = linePart; // linePart ist die richtige
                                sumDistMin = 0;
                                break;
                            }
                        }
                        ILineString segmOffsetLine = gf.CreateLineString(new Coordinate[] { segmentOffset.P0, segmentOffset.P1 });
                        double      distance       = linePart.Distance(segmOffsetLine); // Entfernung des Segments-Endpunktes von der linePart
                        sumDist += distance * segmOffsetLine.Length;
                    }
                    if (sumDistMin > sumDist)
                    {
                        sumDistMin = sumDist;
                        line       = linePart;
                    }
                }
                if (sumDistMin > baseline.Length * offsetAbs)
                {                                                   // die gefundene Linie ist wahrscheinlich doch nicht die richtige
                    line = partialOffsetLine(gf, baseline, offset); // aufteilen und für beiden Teilen versuchen
                    if (line == null)
                    {
                        return(null);
                    }
                    IGeometry lineOnBuffer = line.Intersection(buffer.Buffer(THIN));
                    {  // di OffsetlLinie muß auf dem Buffer sein
                        if (lineOnBuffer is LineString)
                        {
                            return(line);
                        }
                    }
                    return(null);
                }
            }

            // 5. Schritt: eventuell die Linie umdrehen
            {
                Coordinate[] coords        = line.Coordinates;
                IPoint       baseLineBeg   = gf.CreatePoint(baseCoords[0]);
                IPoint       baseLineEnd   = gf.CreatePoint(baseCoords[baseCoords.Length - 1]);
                Coordinate   offsetLineBeg = coords[0];
                Coordinate   offsetLineEnd = coords[coords.Length - 1];
                double       distBegBeg    = baseLineBeg.Coordinate.Distance(offsetLineBeg);
                double       distEndBeg    = baseLineEnd.Coordinate.Distance(offsetLineBeg);
                double       distBegEnd    = baseLineBeg.Coordinate.Distance(offsetLineEnd);
                double       distEndEnd    = baseLineEnd.Coordinate.Distance(offsetLineEnd);

                double maxDiff = offsetAbs + THIN;
                if (distBegEnd < maxDiff && distEndBeg < maxDiff && !(distBegBeg < maxDiff && distEndEnd < maxDiff))
                {
                    line = reverse(line);
                }
                else if (distBegBeg < maxDiff && distEndEnd < maxDiff && !(distBegEnd < maxDiff && distEndBeg < maxDiff))
                {
                    // line = line;
                }
                else
                {
                    // Ergebnis ist nicht befriedigend
                    // Buffer zu groß zu den Liniensegmenten
                    return(partialOffsetLine(gf, baseline, offset));  // aufteilen und für beiden Teilen versuchen
                }
            }

            return(line);
        }
Ejemplo n.º 5
0
        /**
         * die Linie auf 2 Teile zerlegen und für beiden Teilen rekursiv die Offsetlinie erzeugen
         * @param gf
         * @param baseline
         * @param offset
         * @return
         */
        public static ILineString partialOffsetLine(IGeometryFactory gf, ILineString baseline, double offset)
        {
            Coordinate[] coords = baseline.Coordinates;
            if (coords.Length < 4)
            {                 // die Linie hat zu wenig Koordinaten, hat keinen Sinn mehr zu verteilen
                return(null); // Ende der Bemühungen
            }
            List <Coordinate> coordList  = coords.ToList();
            int               halfIndx   = coords.Length / 2;
            Coordinate        midPoint   = new LineSegment(coords[halfIndx - 1], coords[halfIndx]).MidPoint;// bei dem neuen Vertex wird die Linie getrennt
            List <Coordinate> coordList0 = new List <Coordinate>(coordList.Take(halfIndx));

            coordList0.Add(midPoint);
            ILineString       baseLine0  = gf.CreateLineString(coordList0.ToArray()); // erste Hälfte
            List <Coordinate> coordList1 = new List <Coordinate>(coordList.Skip(halfIndx));

            coordList1.Insert(0, midPoint);
            ILineString baseLine1  = gf.CreateLineString(coordList1.ToArray()); // zweite Hälfte
            ILineString shiftLine0 = createOffsetLineNew(gf, baseLine0, offset);
            ILineString shiftLine1 = createOffsetLineNew(gf, baseLine1, offset);

            if (shiftLine0 == null && shiftLine1 == null)
            {
                return(null); // Ende der Bemühungen
            }

            IGeometry buffer = baseline.Buffer(Math.Abs(offset), 12, EndCapStyle.Flat);
            //    Geometry buffer = baseline.buffer(Math.abs(offset), 0, BufferOp.CAP_BUTT);
            IGeometry         bufferBoundary = buffer.Boundary.Buffer(THIN);
            List <Coordinate> shiftCoordList = new List <Coordinate>();

            if (shiftLine0 == null)
            {
                shiftCoordList.AddRange(shiftLine1.Intersection(bufferBoundary).Coordinates);
            }
            else
            if (shiftLine1 == null)
            {
                shiftCoordList.AddRange(shiftLine0.Intersection(bufferBoundary).Coordinates);
            }
            else
            {
                if (shiftLine0.GetPointN(shiftLine0.NumPoints - 1).Distance(shiftLine1.GetPointN(0)) < 2 * THIN)
                {      // Ende der ersten Linie ist bei Anfang der zweiten Linie
                    shiftCoordList.AddRange(shiftLine0.Coordinates);
                    shiftCoordList.AddRange(shiftLine1.Coordinates);
                    shiftCoordList.RemoveAt(shiftLine0.NumPoints);      // doppelter Punkt nur einmal
                }
                else
                {      // Ende erster Linie ist nicht Anfang zweiter Linie
                    shiftCoordList = concat(shiftLine0, shiftLine1);
                    //          List<Coordinate> list0 = Arrays.asList(shiftLine0.intersection(bufferBoundary).getCoordinates());
                    //          shiftCoordList.addAll(list0);
                    //          List<Coordinate> list1 = Arrays.asList(shiftLine1.intersection(bufferBoundary).getCoordinates());
                    //          shiftCoordList.addAll(list1);
                }
            }
            if (shiftCoordList.Count < 2)
            {
                return(null);
            }
            ILineString shiftLine = gf.CreateLineString(shiftCoordList.ToArray());

            if (shiftLine.Length < 3 * SIGNIFICANTDIST)
            {  // 3-fache Distanz, damit die reduzierte Linie auch größer wird als die Distanz
                return(null);
            }

            return(checkLineString(gf, shiftLine, SIGNIFICANTDIST, false));
        }