Giter VIP home page Giter VIP logo

Comments (6)

KubaSzostak avatar KubaSzostak commented on September 22, 2024

Hi @Em3a-c, more explanation will be needed here. I suppose, you are reading the Shapefile and then you are creating geometries for Bing Maps control, right? Can you provide the code that generates those geometries?

I checked the Shapefile with PostGIS and everything seems to be fine.

var geoms = features.Select(f => $"'{f.Geometry.ToText()}'::geometry \r\n");
var sql = "SELECT " + string.Join("UNION ALL SELECT ", geoms);

image

from nettopologysuite.io.esri.

Em3a-c avatar Em3a-c commented on September 22, 2024

Hi @KubaSzostak,

The shapefiles are being read in with:

public IEnumerable<Geometry> GetShapeFileGeometries(string filePath)
{
    var geometries = new List<Geometry>();

    var opts = new ShapefileReaderOptions()
    {
        GeometryBuilderMode = GeometryBuilderMode.IgnoreInvalidShapes
    };

    foreach (var feature in Shapefile.ReadAllFeatures(filePath, opts))
    {
        if (feature.Geometry.IsValid)
        {
            geometries.Add(feature.Geometry);
        }
    }
    return geometries;
}

The geometries are used to create a collection of Microsoft.Maps.MapControl.WPF.MapShapeBase objects. I suspect that the logic here is not correct..
I've not included point/polyline creation, as these 'seem' to render ok.

class MapPolygonShapesFactory
{
    public IEnumerable<MapShapeBase> BuildShapes(IEnumerable<NetTopologySuite.Geometries.Geometry> geometries)
    {
        var mapShapes = new List<Microsoft.Maps.MapControl.WPF.MapShapeBase>();

        foreach (var geometry in geometries)
        {
            NetTopologySuite.Geometries.GeometryFactory factory = geometry.Factory;
            NetTopologySuite.Geometries.Coordinate[] coordinates = geometry.Coordinates;
            NetTopologySuite.Geometries.Point[] points = coordinates.Select(factory.CreatePoint).ToArray();

            if (points.Count() < 1) continue;

            var mapPolygon = new MapPolygon
            {
                Locations = CreateLocationCollection(points),
                Stroke = new SolidColorBrush(Colors.Black),
                Fill = new SolidColorBrush(Colors.Orange),
                StrokeThickness = 2
            };
            mapShapes.Add(mapPolygon);
        }

        return mapShapes.ToArray();
    }

    private LocationCollection CreateLocationCollection(Point[] points)
    {
        var locations = new LocationCollection();
        foreach (var point in points)
        {
            // For the Location construction, pass in point.Y for latitude and point.X for longitude.
            locations.Add(new Microsoft.Maps.MapControl.WPF.Location(point.Y, point.X));
        }
        return locations;
    }
}

This bit is probably not that important, but the collection of Microsoft.Maps.MapControl.WPF.MapShapeBase are then added to a Microsoft.Maps.MapControl.WPF.MapLayer in a viewmodel, i.e

public void AddShapesToMap(IEnumerable<MapShapeBase> shapes)
{
     var mapLayer = new MapLayer();
 
     foreach(var shape in shapes)
     {
         mapLayer.Children.Add(shape);
     }
     MapLayers.Add(mapLayer);
     MapLayers = new []{mapLayer};  // Only allow one map layer in this code snippet.
}

public MapLayer[] MapLayers{ get; set; } 

The Microsoft.Maps.MapControl.WPF.MapLayer is then bound to the Microsoft.Maps.MapControl.WPF.MapItemsControl in the view (xaml).

<m:Map ...>
    <m:MapItemsControl ItemsSource="{Binding Path=MapLayers}"/>
</m:Map>

I suspect the problem is how I'm creating the MapShapeBase objects from the geometry coordinates..

Thanks alot for your help,

Emma

from nettopologysuite.io.esri.

FObermaier avatar FObermaier commented on September 22, 2024

For MultiPolygons and/or Polygons with interior holes your transformation is not correct. You must not use all Coordinates of those geometries to build a MapShape but use each component's Coordinates by itself:

public IEnumerable<MapShapeBase> BuildShapes(IEnumerable<NetTopologySuite.Geometries.Geometry> geometries)
{
    var mapShapes = new List<Microsoft.Maps.MapControl.WPF.MapShapeBase>();

    foreach (var geometry in geometries)
    {
        for (int i = 0; i < geometry.NumGeometries; i++) {
            var itm = geometry.GetGeometryN(i);
            if (!(itm is Polygon polygon)) continue;
            NetTopologySuite.Geometries.GeometryFactory factory = polygon.Factory;
            
            // outer shell
            NetTopologySuite.Geometries.Coordinate[] coordinates = polygon.ExteriorRing.Coordinates;
            /* transform steps for outer shell of wpf map polygon*/
            
            for (int j = 0; j < polygon.NumInteriorRings; j++) {
                coordinates = polygon.GetInteriorRingN(j).Coordinates;
                /* transform steps for inner hole of wpf map polygon*/
            }
            // build map polygon
            var mapPolygon = /* sth. */
            mapShapes.Add(mapPolygon);
        }
    }

    return mapShapes.ToArray();
}

from nettopologysuite.io.esri.

Em3a-c avatar Em3a-c commented on September 22, 2024

I'll have to do some reading around ExteriorRing & GetInteriorRingN property/method, and try to get a working solution. Thanks for your suggestions @FObermaier

from nettopologysuite.io.esri.

KubaSzostak avatar KubaSzostak commented on September 22, 2024

Hi @Em3a-c, do you need more support on this issue? If so, provide further details, please.

from nettopologysuite.io.esri.

Em3a-c avatar Em3a-c commented on September 22, 2024

Hi @KubaSzostak,

I haven't yet managed to get this working, having tried using the suggestion above from @FObermaier,
If no one else can reproduce this issue, then maybe it's worth closing this issue for now, and when I next get a chance, I'll look at this again, and see if I can get a working solution.

Thanks

from nettopologysuite.io.esri.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.