Сопоставление функции GeoJson со свойством - PullRequest
0 голосов
/ 29 октября 2019

Я пытаюсь сопоставить Multipolygon из имеющейся у меня коллекции GeoJSON FeatureColite со свойством Multipolygon типа NetTopologySuite.

Вот что я получил:

GeoJSON:

{"type":"FeatureCollection","features":[{"type":"Feature","geometry":{"bbox":[13.55188823869398,44.440081209521175,16.6289966237125,46.16059787999315],"type":"MultiPolygon","coordinates":[[[[15.395583981629768,44.57162377024533],[15.387003350545871,44.481720735232564],[15.261789625068943,44.48813408824978],[15.270172550335417,44.578048939581144],[15.395583981629768,44.57162377024533]]],[[[15.896964543940912,44.544415530182626],[16.022240457648902,44.53723684127118],[16.14748751000305,44.52990760944508],[16.137724258293254,44.440081209521175],[16.012673860640266,44.44739698760816],[15.88759478603406,44.45456249478511],[15.76248761526664,44.46157767625901],[15.771660353342368,44.55144362101705],[15.896964543940912,44.544415530182626]]],[[[15.152955209351642,44.674242834298695],[15.027294842687972,44.6803775578638],[15.035349165740053,44.770301745657044],[15.161209210808025,44.764155656145604],[15.152955209351642,44.674242834298695]]],[[[15.395583981629768,44.57162377024533],[15.40420062719178,44.661519892738035],[15.52978449007481,44.65493177334668],[15.538636545464684,44.74480883793866],[15.664392732134285,44.73805721601009],[15.655341665136223,44.64819262251561],[15.646328471445097,44.55832105973176],[15.520969484947091,44.56504779340633],[15.395583981629768,44.57162377024533]]],[[[15.906373586831855,44.63426143624865],[15.780871560861883,44.641302492390295],[15.790121463337991,44.731154339362874],[15.915822144904903,44.7241002616354],[15.906373586831855,44.63426143624865]]],[[[14.909464652174844,44.77629632941221],[14.783556270565919,44.78213936065267],[14.791243042374749,44.8720788835874],[14.917352248635115,44.86622499380096],[14.909464652174844,44.77629632941221]]],[[[15.40420062719178,44.661519892738035],[15.278590669072724,44.667956929679484],[15.28704418791397,44.75785810878928],[15.295533315163146,44.84775252708752],[15.421542808951754,44.84129159985158],[15.412853498605203,44.751409152650304],[15.40420062719178,44.661519892738035]]],[[[15.295533315163146,44.84775252708752],[15.169497988826626,44.854061767894706],[15.17782174856998,44.943961219958226],[15.304058260811797,44.937640234683336],[15.295533315163146,44.84775252708752]]],[[[15.67348189503577,44.82791488944938],[15.547525868962715,44.83467903673759],[15.55645268017813,44.92454241922587],[15.682609378238029,44.91776569199236],[15.67348189503577,44.82791488944938]]],[[[15.574419653120414,45.10424893283504],[15.447831530393547,45.11089856282971],[15.456668762059818,45.20075425647369],[15.583460263041763,45.19409216255446],[15.574419653120414,45.10424893283504]]],[[[15.084394984513631,45.309708772973096],[15.076133963305915,45.21982378925574],[14.94923765800067,45.2258745480123],[14.941215654803312,45.13597182321009],[14.814498911953551,45.1418585743132],[14.822316698924032,45.23177234906947],[14.695371707066238,45.237517145249605],[14.703017502529459,45.32743542422996],[14.710695871844338,45.4173474925388],[14.8380521975077,45.41158102170872],[14.830167727940616,45.321679814539486],[14.957293763601468,45.315770914953696],[14.965384175175874,45.40566097472601],[15.092691175810298,45.39958739941671],[15.084394984513631,45.309708772973096]]],[16.19120538066795,46.06345399526351],[16.062454717796655,46.07086579545412]]]]},"properties":{"code":"1167","maptype":"Distribution","category":"Species","isocode":"HR","refgrid":"EEA 10x10km","sensitive":"non-sensitive"}}],"fileName":"Test"}

Моя модель:

public class Species
    {
        public int Id { get; set; }
        public string Name { get; set; }
        //property to which I want to map the MultiPolygon feature from GeoJSON. This is a NetToplogySuite type.
        public MultiPolygon Range { get; set; }
    }

Я пытался использовать библиотеки NetTopologySuite и GeoJSON.Net для преобразования и отображения GeoJSON, но я не продвинулся далеко. Я получаю GeoJSON в виде строки в моем контроллере:

using NetTopologySuite.IO;
using NetTopologySuite.Geometries;
using GeoJSON.Net.Feature;
using GeoJSON.Net;

    public void GeoJson(string json)
            {

                Species newSpecies = new Species();

                var reader = new GeoJsonReader();
                var featureCollection = reader.Read<FeatureCollection>(json);

                if (featureCollection == null)
                {
                    return;
                }

                // loop through all the parsed features
                for (int featureIndex = 0;
                     featureIndex < featureCollection.Features.Count;
                     featureIndex++)
                {
                    // get json feature
                    var jsonFeature = featureCollection.Features[featureIndex];
                    Geometry geom = null;

                    // get geometry type to create appropriate geometry
                    switch (jsonFeature.Geometry.Type)
                    {
                        case GeoJSONObjectType.Point:
                            break;
                        case GeoJSONObjectType.MultiPoint:
                            break;
                        case GeoJSONObjectType.LineString:
                            break;
                        case GeoJSONObjectType.MultiLineString:
                            break;
                        case GeoJSONObjectType.Polygon:
                            break;
                        case GeoJSONObjectType.MultiPolygon:
                            {
                                //this is where I want to convert GeoJSON MultiPolygon to a NetToplogySuite MultiPolygon but I'm don't know how. Basically I want to map the newSpecies.Range to the MultiPolygon jsonFeature. 

                            }
                            break;
                        case GeoJSONObjectType.GeometryCollection:
                            break;
                        case GeoJSONObjectType.Feature:
                            break;
                        case GeoJSONObjectType.FeatureCollection:
                            break;
                        default:
                            throw new ArgumentOutOfRangeException();
                    }
                }
            }

Есть идеи?

Спасибо!

1 Ответ

0 голосов
/ 31 октября 2019

Вот решение, которое мне удалось написать после нескольких дней проб и ошибок. По сути, geoJSON представляет собой строку, преобразуется в JSON с использованием метода Parse из Newtonsoft.Json, а затем в коллекцию FetureCollection с использованием GeoJsonReader из GeoJSON.NET. Затем я перебираю все проанализированные элементы и создаю соответствующую геометрию. В этом случае меня интересовала только функция Multipolygon, которую я преобразовал в тип Multipolygon из NetTopologySuite.

using NetTopologySuite.IO;
using NetTopologySuite.Geometries;
using GeoJSON.Net.Feature;
using GeoJSON.Net;

[HttpPost]
public void GeoJson(string json) {
 var test = json;
 var item = JObject.Parse(json);

 Species newSpecies = new Species();

 var reader = new GeoJsonReader();
 var featureCollection = reader.Read < FeatureCollection > (json);

 if (featureCollection == null) {
  return;
 }

 // loop through all the parsed features
 for (int featureIndex = 0; featureIndex < featureCollection.Features.Count; featureIndex++) {
  // get json feature
  var jsonFeature = featureCollection.Features[featureIndex];

  // get geometry type to create appropriate geometry
  switch (jsonFeature.Geometry.Type) {
   case GeoJSONObjectType.Point:
    break;
   case GeoJSONObjectType.MultiPoint:
    break;
   case GeoJSONObjectType.LineString:
    break;
   case GeoJSONObjectType.MultiLineString:
    break;
   case GeoJSONObjectType.Polygon:
    break;
    //ovo trenutno ima smisla samo ako se distribucija prikazuje samo kao jedan Feature u FeatureListi
    //moram razmisliti kako to napraviti ako je slučaj više multipoligona i kako ih kombinirati
   case GeoJSONObjectType.MultiPolygon:
    {
     var multipoly = jsonFeature.Geometry as GeoJSON.Net.Geometry.MultiPolygon;
     var polygonList = new List < Polygon > ();
     foreach(var firstLevel in multipoly.Coordinates) {
      var firstLevelCoordinateList = new List < List < Coordinate >> ();

      foreach(var secondLevel in firstLevel.Coordinates) {

       var secondLevelCoordinateList = new List < Coordinate > ();
       foreach(var thirdLevel in secondLevel.Coordinates) {
        var coordinates = new Coordinate(thirdLevel.Longitude, thirdLevel.Latitude);
        secondLevelCoordinateList.Add(coordinates);
       }

       var coordArr = new Coordinate[secondLevelCoordinateList.Count];

       for (int i = 0; i < secondLevelCoordinateList.Count; i++) {
        coordArr[i] = secondLevelCoordinateList[i];
       }
       var poly = new GeometryFactory().CreatePolygon(coordArr);
       polygonList.Add(poly);
       firstLevelCoordinateList.Add(secondLevelCoordinateList);
      }

     }
     var polyArr = new Polygon[polygonList.Count];

     for (int i = 0; i < polygonList.Count; i++) {
      polyArr[i] = polygonList[i];
     }
     //NetTopologySuite Multipolygon property
     newSpecies.Range = new GeometryFactory().CreateMultiPolygon(polyArr);
    }
    break;
   case GeoJSONObjectType.GeometryCollection:
    break;
   case GeoJSONObjectType.Feature:
    break;
   case GeoJSONObjectType.FeatureCollection:
    break;
   default:
    throw new ArgumentOutOfRangeException();
  }
 }
}
...