Daha çox

NetTopologySuite istifadə edərək dönüş nöqtəsi


Bir geoprosessing vəzifəsini həll etmək üçün NetTopologySuite -dən necə istifadə edə biləcəyimizi araşdırıram. Tapdığım bəzi kod nümunələrinə əsaslanaraq, bir şəkil faylını oxuyan və bir nöqtənin bir çoxbucaqlı yerə düşüb -düşmədiyini yoxlayan bir nümunə proqramı bir araya gətirə bildim. Məsələ burasındadır ki, fikrim WGS84 -dədir, lakin şəkil formatı EPSG -dədir: 2810. Giriş nöqtəsini şəkil faylının CRS -ə çevirməliyəm.

NetTopologySuite 1.13.3 istifadə edərək bir nöqtəni WGS -dən EPSG: 2810 -a necə çevirə bilərəm?

İndiyə qədər əldə etdiyim kodlardan bəziləri:

string shpFilename = @"C: …  polygons.shp"; GeometryFactory fabriki = yeni GeometryFactory (); var coord = yeni Koordinat (-90.00, 45.00); var point = zavod.CreatePoint (koordinat);

Onu da qeyd etməliyəm ki, WGS84 -dən əl ilə proqnozlaşdırılan sistemə çevirəndə və bu çevrilmiş dəyərləri istifadə edərkən, kodum nəzərdə tutulduğu kimi işləyir. Bu, bir çoxbucaqlının içərisinə düşüb -düşmədiyini təyin etməzdən əvvəl koordinatların dəyişdirilməsi məsələsi olduğunu təsdiqləyir.


NTS-də nöqtədən nöqtəyə koordinat çevirmənin standart yolu ProjNet4GeoAPI kitabxanasından istifadə etməkdir.

Vahid testlərindən götürülmüş bir koordinat çevrilməsi nümunəsi:

ictimai boşluq TestTransformListOfCoordinates () {CoordinateSystemFactory csFact = new CoordinateSystemFactory (); CoordinateTransformationFactory ctFact = yeni CoordinateTransformationFactory (); ICoordinateSystem utm35ETRS = csFact.CreateFromWkt ("PROJCS [" ETRS89 / ETRS-TM35  ", GEOGCS [" ETRS89  ", DATUM [" D_ETRS_1989  ", SPHEROID [ 2,2 638791]" 222 ") PRIMEM [ "Greenwich ", 0], UNIT [ "Degree ", 0.017453292519943295]], PROJEKSİYON [ "Transverse_Mercator "], PARAMETRE [ "latitude_of_origin ", 0], PARAMETRE [ "central_meridian " , 27], PARAMETR [ "miqyaslı_faktor ", 0.9996], PARAMETER [ "yalançı_ötürmə ", 500000], PARAMETRE [ "yalan_northing ", 0], Vahid [ "Metr ", 1]] ") ; IProjectedCoordinateSystem utm33 = ProjectedCoordinateSystem.WGS84_UTM (33, doğru); ICoordinateTransformation trans = ctFact.CreateFromCoordinateSystems (utm35ETRS, utm33); Koordinat [] nöqtələri = yeni Koordinat [] {yeni Koordinat (290586.087, 6714000), yeni Koordinat (290586.392, 6713996.224), yeni Koordinat (290590.133, 6713973.772), yeni Koordinat (290594.111, 6713957.416), yeni yeni Koordinat (290596.701, 6713939.485)}; Koordinat [] tpoints = trans.MathTransform.TransformList (bal) .ToArray (); for (int i = 0; i 

Eyni ehtiyacla qarşılaşdı. Testdən bir nümunə də tapdım. Detalları açıqladılar. Ancaq bu yanaşma IGeometry növü (IPoint, ILineString və s.) İlə işləyərkən əlverişli deyil.

Bir az araşdırmadan sonra həndəsəni daha əlverişli bir şəkildə necə dəyişdirəcəyimi tapdım (NTS github deposu sayəsində :)

1) çevrilmə yaratmalıyıq:

ICoordinateTransformation Wgs84ToWebMercator = (yeni CoordinateTransformationFactory ()) .CreateFromCoordinateSystems (GeographicCoordinateSystem.WGS84, ProjectedCoordinateSystem.WebMercator);

2) həndəsə ardıcıllığı ilə təkrarlanan və bütün işləri görən filtri elan edin:

ictimai sinif CoordinateTransformationFilter: ICoordinateSequenceFilter {private readonly ICoordinateTransformation _transformation; public CoordinateTransformationFilter (ICoordinateTransformation transformation) {_transformation = transformasiya ?? yeni ArgumentNullException atın ($ "{nameof (transformasiya)} sıfır ola bilməz."); } ///  /// Bəli, həmişə doğrudur. ///  public bool Bitti => doğru; ///  /// Transformasiyadan sonra avtomatik zəng IGeometry.GeometryChanged () metodu. ///  ictimai bool GeometryChanged => doğru; ictimai boşluq Filtri (ICoordinateSequence seq, int i) {_transformation.MathTransform.Transform (seq); }}

3) filtr yaradın:

var transformFilter = yeni CoordinateTransformationFilter (Wgs84ToWebMercator);

4) Mənfəət:

// WGS84 -də (aka EPSG: 4326) hər hansı bir yerdən nöqtə alın IPoint srcPoint =…; // Atlaya bilərsiniz. Ancaq həndəsəniz dəyişəcək. IPoint projectedPoint = srcPoint.Clone () IPoint olaraq; // Sehr burada baş verir. WebMercator -dakı nöqtəmiz (aka EPSG: 3857) projectedPoint.Apply (transformFilter);

YENİLƏNİB 2019-07-09: ProjNET4GeoAPI v1.4.1 üçün bu həll. Yeni versiya ilə işləməyəcəyini düşünürəm.


Cavab ballarla yaxşı işləyir. Ancaq bunu çuxurlu çoxbucaqlılarla etsəniz, nöqtələr sıradan çıxacaq. Sonra bu nöqtələri çoxbucağa çevirdikdə LineStrings -in bağlanmamasından şikayətlənəcək.

Çevrimimi qurmaq üçün ProjNet kitabxanasından istifadə etməyi bitirdim və sonra NetTopologySuite çoxbucaqlıları idarə edən bir proqrama sahib oldu.

Belə bir şeyə bənzəyir. WKT proyeksiya mətnini SpatialReference.org saytından əldə edə bilərsiniz. Bunu bütün həndəsə növləri üçün asanlıqla genişləndirə bilərsiniz.

statik GeoAPI.Geometries.IPolygon ProjectGeometry (GeoAPI.Geometries.IPolygon polygeo, FromWKT simli, ToWKT simli) {var SourceCoordSystem = new CoordinateSystemFactory (). CreateFromWkt (FromWKT); var TargetCoordSystem = yeni CoordinateSystemFactory (). CreateFromWkt (ToWKT); var trans = new CoordinateTransformationFactory (). CreateFromCoordinateSystems (SourceCoordSystem, TargetCoordSystem); var poly = NetTopologySuite.CoordinateSystems.Transformations.GeometryTransform.TransformPolygon (polygeo.Factory, polygeo, trans.MathTransform); geri qaytarma poli; }

Yeniləyin
Yuxarıdakı kod NetTopologySuite -in yeni versiyası ilə işləmir. Aşağıda NetTopologySuite 2.0.0 ilə işləyən yenilənmiş bir versiya verilmişdir.

statik NetTopologySuite.Geometries.Geometry ProjectGeometry (NetTopologySuite.Geometries.Geometry geom, string FromWKT, string ToWKT) {var SourceCoordSystem = new CoordinateSystemFactory (). CreateFromWkt (FromWKT); var TargetCoordSystem = yeni CoordinateSystemFactory (). CreateFromWkt (ToWKT); var trans = new CoordinateTransformationFactory (). CreateFromCoordinateSystems (SourceCoordSystem, TargetCoordSystem); var projGeom = Transform (geom, trans.MathTransform); qaytar projGeom; } statik NetTopologySuite.Geometries.Geometry Transform (NetTopologySuite.Geometries.Geometry geom, MathTransform transform) {geom = geom.Copy (); geom.Apply (yeni MTF (çevrilmə)); geri geom; } möhürlənmiş sinif MTF: NetTopologySuite.Geometries.ICoordinateSequenceFilter {şəxsi oxumaq üçün MathTransform _mathTransform; ictimai MTF (MathTransform mathTransform) => _mathTransform = mathTransform; public bool Bitti => yalan; ictimai bool GeometryChanged => doğru; ictimai boşluq Filtri (NetTopologySuite.Geometries.CoordinateSequence seq, int i) {double x = seq.GetX (i); ikiqat y = seq.GetY (i); ikiqat z = seq.GetZ (i); _mathTransform.Transform (ref x, ref y, ref z); seq.SetX (i, x); seq.SetY (i, y); seq.SetZ (i, z); }}