Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

I would like to use NetTopologySuite to convert a CompositeCurve to a MultiLineString. I would like to find some code which shows how to convert this to a MultiLineString:

  <gml:CompositeCurve srsName="EPSG:4326"
  xmlns:gml="http://www.opengis.net/gml">
    <gml:curveMember>
      <gml:LineString srsName="EPSG:4326">
        <gml:posList srsDimension="2">46.2072145436504 -119.242266357388
        46.2081175005802 -119.239767847285 46.2085501572205
        -119.238573244775</gml:posList>
      </gml:LineString>
    </gml:curveMember>
    <gml:curveMember>
      <gml:Curve srsName="EPSG:4326">
        <gml:segments>
          <gml:Arc interpolation="circularArc3Points">
            <gml:posList srsDimension="2">46.2085501572205 -119.238573244775
            46.2086267189565 -119.238351385025 46.2086927116396
            -119.238126155333</gml:posList>
          </gml:Arc>
        </gml:segments>
      </gml:Curve>
    </gml:curveMember>
    <gml:curveMember>
      <gml:LineString srsName="EPSG:4326">
        <gml:posList srsDimension="2">46.2086927116396 -119.238126155333
        46.2087174795272 -119.238053558363</gml:posList>
      </gml:LineString>
    </gml:curveMember>
  </gml:CompositeCurve>

Here is a draft of my code but "Curve" handling is just a bad guess of how to handle this:

private IGeometry GetGeometry ( XElement shapeNode )
{
    if ( null == shapeNode ) return null;
    var geoType = shapeNode.Name;

    // TODO: not sure what the rule is here...but GML 3.0 introduced the <gml:pos> and <gml:posList>
    // esri wfs 1.1.0 uses gml 3.1.1,
    // see http://home.gdal.org/projects/gml/gml_interop.html
    var geoCoordinates = shapeNode.XPathSelectElement("//gml:coordinates", _nsmgr) ??
                         (shapeNode.XPathSelectElement("//gml:pos", _nsmgr) ??
                          shapeNode.XPathSelectElement("//gml:posList", _nsmgr));

    double[] points;

    if (null != geoCoordinates)
    {
        points =
            geoCoordinates.Value.Split(" ,\r\n\t".ToCharArray(), StringSplitOptions.RemoveEmptyEntries).Select(Double.Parse)
                .ToArray();
    }
    else
    {
        geoCoordinates = shapeNode.XPathSelectElement("//gml:coord", _nsmgr);
        points = new[]
            {
                Double.Parse(geoCoordinates.XPathSelectElement("gml:X", _nsmgr).Value),
                Double.Parse(geoCoordinates.XPathSelectElement("gml:Y", _nsmgr).Value)
            };
    }
    var coordinates =
        points.Where((a, b) => 0 == b%2).Zip(points.Where((a, b) => 1 == b%2), (a, b) => new Coordinate(a, b)).ToArray();

    switch (geoType.LocalName)
    {
        case "Point":
            return new Point(coordinates.First());
        case "Curve":
            {
                var precisionModel = new PrecisionModel(PrecisionModels.Floating);
                var bufParams = new BufferParameters();
                var b = new OffsetCurveBuilder(precisionModel, bufParams);
                return new LineString(b.GetLineCurve(coordinates.ToArray(), 0));
            }
        case "curveMember":
            return shapeNode.Elements ( ).Select ( GetGeometry ).FirstOrDefault();
        case "CompositeCurve":
            {
                var shapes = shapeNode.Elements().Select(GetGeometry);
                var lines = shapes.Select(s => new LineString(s.Coordinates.ToArray()));
                return new MultiLineString(lines.ToArray());
            }
        case "Line":
        case "LineString":
            return new LineString(coordinates.ToArray());
        case "MultiLineString":
            return new LineString(coordinates.ToArray());
        case "MultiSurface":
            return new LineString(coordinates.ToArray());
        case "CompositeSurface":
            return new LineString(coordinates.ToArray());
        case "Box":
            var sw = coordinates.First();
            var ne = coordinates.Skip(1).First();
            var shell = new LinearRing(new[]
                {
                    sw,
                    new Coordinate(ne.X, sw.Y),
                    ne,
                    new Coordinate(sw.X, ne.Y),
                    sw
                });
            return new Polygon(shell);
        case "Polygon":
            shell = new LinearRing(coordinates.ToArray());
            return new Polygon(shell);
        case "MultiPolygon":
            shell = new LinearRing(coordinates.ToArray());
            return new Polygon(shell);
        default:
            throw new ApplicationException(string.Format("Unknown Geometry Type: {0}", geoType));
    }
}
share|improve this question
    
I just discovered NetTopologySuite.IO.GML2.GMLReader but that does not handle curves (code.google.com/p/nettopologysuite/source/browse/trunk/…). –  ca0v Sep 11 '12 at 15:42
add comment

1 Answer 1

Since NTS supports Simple SQL specification, there isn't native curve handling. Your code looks ok, but you can ask for a better solution in the JTS mailing list (http://sourceforge.net/mailarchive/forum.php?forum_name=jts-topo-suite-user). The code is the same for NTS.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.