gpt4 book ai didi

c# - 将 GeoJson 特征映射到属性

转载 作者:行者123 更新时间:2023-12-02 00:12:15 30 4
gpt4 key购买 nike

我正在尝试将 GeoJSON FeatureCollection 中的多面体映射到一个属性,该属性是 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 转换和映射,但我没有取得太大进展。我在我的 Controller 中接收 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();
}
}
}

有什么想法吗?

谢谢!

最佳答案

在阅读了互联网上几乎所有的页面后,我重构了你的答案(我相信)是一个复制和粘贴错误。除了添加到之外,我永远无法找出您使用 firstLevelCoordinateList 的目的。

所以,我重构了你的代码。此版本可能包含 GeoJSON.Net 的痕迹,但我试图删除它的痕迹并将其完全基于 NetTopologySuite。然而,后来又出现了另一种解决方案……

using GeoJSON.Net;
using GeoJSON.Net.Contrib.EntityFramework;
using GeoJSON.Net.Feature;
using NetTopologySuite.Geometries;
using NetTopologySuite.Geometries.Implementation;
using RekylService.ExternalSync.DataPortal.Imports.Interfaces;
using System.Collections.Generic;
using System.Linq;
using LineString = GeoJSON.Net.Geometry.LineString;
using MultiLineString = GeoJSON.Net.Geometry.MultiLineString;
using MultiPoint = GeoJSON.Net.Geometry.MultiPoint;
using MultiPolygon = GeoJSON.Net.Geometry.MultiPolygon;
using Point = GeoJSON.Net.Geometry.Point;
using NTS = NetTopologySuite;

namespace Parser
{
public class GeoShapeJsonParser
{
public ICollection<Geometry> ParseGeoShapes(string data)
{
var reader = new NTS.IO.GeoJsonReader();
var featureCollection = reader.Read<FeatureCollection>(data);

if (featureCollection == null)
return null;

var geoFactory = NTS.NtsGeometryServices.Instance.CreateGeometryFactory(srid: 4326);

var shapes = new List<Geometry>();

foreach (var shape in featureCollection.Features)
{
if (shape.Type == GeoJSONObjectType.MultiPolygon)
{
var multipolygon = shape.Geometry as MultiPolygon;

var ringList = new List<NTS.Geometries.LinearRing>();
var polygonList = new List<NTS.Geometries.Polygon>();

foreach (var xpolygon in multipolygon.Coordinates) //I had a name conflict, hence xpolygon instead of polygon ;)
{
foreach (var lineString in xpolygon.Coordinates) //the first lineString is the shell, and the ones following are holes
{
var linearRingCoordinates = new List<NTS.Geometries.Coordinate>();

foreach (var coordinate in lineString.Coordinates)
{
var coordinates = new NTS.Geometries.Coordinate(coordinate.Longitude, coordinate.Latitude);

linearRingCoordinates.Add(coordinates);
}

var ring = geoFactory.CreateLinearRing(linearRingCoordinates.ToArray());

ringList.Add(ring);
}

var polygon = geoFactory.CreatePolygon(ringList.First(), ringList.Skip(1).ToArray()); //this takes the first ring as outer shell and the rest as holes

polygonList.Add(polygon);
}

shapes.Add(geoFactory.CreateMultiPolygon(polygonList.ToArray()));
}
}

return shapes;

此解决方案还考虑了多边形中的孔洞。不过,关键来了(现在 100% NetTopologySuite,以及所有形状):

    public class GeoShapeJsonParser
{
public ICollection<Geometry> ParseGeoShapes(string data)
{
var reader = new GeoJsonReader();
var featureCollection = reader.Read<FeatureCollection>(data);

var shapes = new List<Geometry>();

foreach (var feature in featureCollection)
shapes.AddRange(Extract(feature));
}

public IEnumerable<Geometry> Extract(IFeature feature)
{
var extract = new List<Geometry>();

new GeometryExtracter<Point>(extract).Filter(feature.Geometry);
new GeometryExtracter<MultiPoint>(extract).Filter(feature.Geometry);
new GeometryExtracter<LineString>(extract).Filter(feature.Geometry);
new GeometryExtracter<MultiLineString>(extract).Filter(feature.Geometry);
new GeometryExtracter<LinearRing>(extract).Filter(feature.Geometry);
new GeometryExtracter<Polygon>(extract).Filter(feature.Geometry);
new GeometryExtracter<MultiPolygon>(extract).Filter(feature.Geometry);

return extract;
}

这绝对是解析所有 geoshapes 的最佳、最短和最快的方法。我对缺乏关于该主题的文档感到惊讶。

为了将其保存到 SQL 服务器,我将每个形状制作成 WKT,然后使用 “提取的几何对象”.ToText() 将它们发送出去。

在存储库中,我将它们作为 DbGeography.FromText("the extracted geometry object") 分配给字段。

关于c# - 将 GeoJson 特征映射到属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58609043/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com