Mehr

So erhalten Sie die Anzahl der Polygone einer Geometrie in PostgreSQL

So erhalten Sie die Anzahl der Polygone einer Geometrie in PostgreSQL


Wie kann ich die Anzahl der Polygone ermitteln, die in PostgreSQL eine Geometrie bilden?

Zum Beispiel hat die US-Karte neben den Hauptländern viele Inseln. Ich möchte diese Inseln plus die Hauptländer zählen.


Verwenden Sie den Geometrie-Accessor ST_NumGeometries.

Beispielsweise

SELECT ID, ST_NumGeometries(shape) FROM myTable

Wenn Ihre Geometrien andere Geometrietypen als Polygone enthalten, müssen Sie diese aufteilen und vor dem Zählen nur die Polygone behalten. Aber aus Ihrer Frage wäre dies nicht erforderlich.


Laut Dokumentation (Kapitel 7.3) gibt es mehrere Geometrie-Accessoren, die Ihre Kriterien erfüllen könnten, je nachdem, ob es sich bei der Geometrie um eine Sammlung, ein Polygon oder ein Multi-Polygon handelt:

  • ST_NumGeometries - Wenn die Geometrie eine GEOMETRYCOLLECTION (oder MULTI*) ist, die Anzahl der Geometrien zurückgeben, andernfalls NULL zurückgeben.
  • ST_NumInteriorRings - Gibt die Anzahl der inneren Ringe des ersten Polygons in der Geometrie zurück. Dies funktioniert sowohl mit POLYGON- als auch mit MULTIPOLYGON-Typen, betrachtet aber nur das erste Polygon. Gibt NULL zurück, wenn die Geometrie kein Polygon enthält.
  • ST_NRings - Wenn die Geometrie ein Polygon oder Multi-Polygon ist, wird die Anzahl der Ringe zurückgegeben.

Ein strenger Beweis würde so aussehen:

Angenommen, Sie haben ein regelmäßiges Polygon $P$ mit $2n$ Seiten: $A_1A_2. A_nA_. A_<2n>$ . Gemäß der Definition eines regelmäßigen Vielecks sind alle Seiten gleich lang und alle Winkel zwischen aufeinanderfolgenden Seiten müssen gleich sein.

Zuerst müssen Sie beweisen, dass Winkelhalbierende aller Polygonwinkel durch denselben Punkt gehen. Betrachten Sie zum Beispiel Winkelhalbierende von $angle A_1$ und $angle A_2$ . Sie kreuzen sich an einem Punkt $O$ . Die Winkel $angle OA_1A_2$ und $angle OA_2A_1$ sind gleich (genau die Hälfte des Winkels zwischen aufeinanderfolgenden Seiten), also ist das Dreieck $ riangle OA_1A_2$ gleichschenklig und $OA_1=OA_2$ . Genauso können Sie zeigen, dass $OA_2=OA_3$ , . $OA_<2n-1>=OA_<2n>$ , $OA_<2n>=OA_1$ .

Es gibt also einen Punkt O, so dass alle Längen $OA_i$ ( $i$ =1. $2n$ ) gleich sind und dieser Punkt der Mittelpunkt des umschriebenen Kreises ist. Sie können auch leicht beweisen, dass Dreiecke $ riangle OA_iA_$ und $dreieck OA_jA_$ sind kongruent für jedes $i,j$ (weil $OA_i=OA_j$ , $OA_=OA_$ , $A_iA_=A_jA_$ ).

Aus diesem Grund sind alle Winkel $angle A_iOA_$ sind gleich. Bezeichne diesen Winkel mit $alpha$ . Offensichtlich $alpha=2pi/(2n)=pi/n$

Die Dreiecke $ riangle OA_1A_2$ und $ riangle OA_2A_3$ sind deckungsgleich, daher muss eine isometrische Transformation erfolgen, die das erste Dreieck in das zweite umwandelt. Isometrie mit einem Fixpunkt $O$ ist eine Drehung. So:

$R_(Dreieck OA_1A_2)=Dreieck OA_2A_3$

$R_(Dreieck OA_2A_3)=Dreieck OA_3A_4$

$R_<0,pi>(Dreieck OA_1A_2)=Dreieck OA_EIN_$

Mit anderen Worten, wenn Sie einen Punkt $Min P$ haben, der zum Dreieck $ riangle OA_1A_2$ gehört, wandelt die Drehung um den Punkt $O$ für $180^circ$ diesen Punkt in einen Punkt $M'$ um, der zu gehört Dreieck $dreieck OA_EIN_$ d.h. bis zu einem gewissen Punkt $M'in P$ .

Die Drehung um einen Fixpunkt $O$ für $pi=180^circ$ ist eigentlich eine zentrale Symmetrie, wobei $O$ ein Symmetriezentrum ist.

Jedes regelmäßige Polygon mit $2n$ Seiten hat also ein Symmetriezentrum, das auch ein Zentrum eines umschriebenen Kreises ist.


Sie können die Eigenschaft "Interior" verwenden, um Innenflächen von vm zu erhalten:

Verwenden Sie Style[interiorfaceindices, Direktive[EdgeForm[], FaceForm[]]] um zu erhalten:

Konstruieren Sie einen Datensatz mit Kantenzahlen, Flächen und Regionsschwerpunkten von Innenflächen:


2 Antworten 2

OK, ich glaube, ich habe mich in meinem Kommentar falsch erinnert, ich denke, der Umfang ist einfacher zu bearbeiten als der Bereich. Sie beginnen also mit einem Kreis mit dem Umfang $pi$ (also einem Radius von $frac<1><2>$ ). Ermitteln Sie die Länge der Seite des Quadrats (sie ist $frac<1>>$ ), also ist die anfängliche Schätzung $4cdotfrac<1>> = 2sqrt <2>ca. 2.828427$ :

Hier ist ein konkretes Beispiel, in dem wir den vorherigen bekannten Akkord (in diesem Fall $frac<1>>$ ) verwenden können, um den nächsten zu finden:

Dies ergibt $pi approx 3,0614674$ . Nun, hier ist der allgemeine Fall, in dem Sie den vorherigen Akkord, $s_n$ , kennen und dann den nächsten finden (da Sie wissen, dass Sie jedes Mal den vorherigen Akkord halbieren, sodass sich die Anzahl der Seiten verdoppelt). Ich denke, diese Formel ist richtig, die Formel für $s_$ angegeben $s_n$ ist definitiv richtig, weil ich es getestet habe, aber nicht ganz sicher über die Umfangsformel:

Mit obigem können wir schreiben:

Start P_1 ungefähr & 2.8284271247461903 P_2 ungefähr & 3,061467458920718 P_3 ungefähr & 3,121445152258053 P_4 ungefähr & 3.1365484905459406 P_5 ungefähr & 3,140331156954739 P_6 ungefähr &571412 P_4 ca & ca. & 3.1415138011441455 P_8 ca. & 3.1415729403678827 P_9 ca. & 3.141587725279961 P_ <11>ca. & 3.141591421504635 P_ <12>ca. & 3.141592345611077 P_ <13>ca. & 3.1415925765450043 P_ <14>ca. & 3.1415926334632482 P_ <15>ca. & 3.141592654807589 P_ <16>ca. & 3.1415926453212153 P_ <17>ca. & 3.1415926073757197 P_ <18>ca. & 3.1415929109396727 P_ <19>ca. & 3.141594125195191 P_ <20>ca. & 3.1415965537048196 P_ <21>ca. & 3.1415965537048196 end

Dies ergibt eine Genauigkeit von fünf Stellen: $pi approx 3,14159$ .

Dieses Beispiel wurde mir in meinem Scientific Computing-Kurs beigebracht Weg zurück, um Rundungsfehler in Gleitkommaberechnungen anzuzeigen. Sie werden feststellen, dass wir bei den letzten beiden das gleiche Ergebnis erhalten. Das liegt daran, dass die Gleitkommaberechnungen des Computers im Wesentlichen an ihre Grenzen gestoßen sind. Der Grund dafür ist, dass $s_n^2$ so klein geworden ist, dass $1 - s_n^2$ keine "neue" Zahl erzeugt (es gibt einfach immer die gleiche Zahl an, die $s_n^2$ beim Subtrahieren wieder erzeugt) $1$ Es gibt einen Trick, um diese Berechnung zu verbessern:

Das bringt wirklich bessere Ergebnisse:

Start P_1 ca.& 2.8284271247461903 P_2 ca.& 3,0614674589207183 P_3 ca.& 3.1214451522580524 P_4 ca.& 3.1365484905459393 P_5 ca.& 3,140331156954753 P_6 ca approx& 3.1415729403670913 P_9 approx& 3.1415877252771596 P_ <10>approx& 3.1415914215111997 P_ <11>approx& 3.1415923455701176 P_ <12>approx& 3.1415925765848725 ca. P_13> 3.1415926343385627 P_ <14>ca.& 3.1415926487769856 P_ <15>ca.& 3.141592652386591 P_ <16>ca.& 3.141592653288993 P_ <17>ca.& 3.141592653514593 P_ <18>ca.& 3.141592653570993 P_ <19>ca.& 3.1415926535850933 P_ <20>ca.& 3.141592653588618 P_ <21>ca.& 3.1415926535894996 P_ <22>ca.& 3.1415926535897203 P_ <23>ca.& 3.1415926535897754 P_ <24>ungefähr& 3.141592653589789 P_ <25>ungefähr& 3.1415926535897927 P_ <26>a pprox& 3,1415926535897936 P_ <27>approx& 3,1415926535897936 end

Durch einfaches Ändern der Berechnung, nicht der Algorithmus!, wir bekommen jetzt zwölf Ziffern der Präzision! $pi approx 3.141592653589$ --alle wegen eines Gleitkomma-Rundungsfehlers.


2 Antworten 2

Wenn es Löcher gibt, dann gilt die Formel nicht, wie ich bereits kommentiert habe.

Ohne Löcher gilt die Formel.

Betrachten wir im Folgenden verschmolzene Polygone ohne Löcher.

Der Grund, warum die Formel gilt, ist, dass, wenn Sie ein neues Sechseck zu verschmolzenen Polygonen hinzufügen, die folgende Beziehung $( ext)-(Text)=1$ hält.

Man kann beweisen, dass die Formel durch Induktion über die Anzahl der Polygone gilt.

Betrachten wir ein Sechseck, dann gilt $S=A=6$ , also gilt $S-A+1=N$.

Angenommen, $S_F-A_F+1=N$ gilt in den verschmolzenen Polygonen $F$ .

Fall 1 : Wenn Sie $F$ ein Sechseck $H$ hinzufügen, wobei $H$ und $F$ genau eine gemeinsame Kante haben, dann haben wir in den neuen Polygonen $F'$ $N_=N+1,quad S_=S_F+5,quad A_=A_F+4$ Wir sehen also, dass $S_-EIN_+1=N_$ hält.

Fall 2 : Wenn Sie ein Sechseck $H$ zu $F$ hinzufügen, wobei $H$ und $F$ genau zwei gemeinsame Kanten haben (beachten Sie, dass die beiden Kanten benachbart sein müssen), dann haben wir in den neuen Polygonen $F'$ $N_=N+1,quad S_=S_F+4,quad A_=A_F+3$ Wir sehen also, dass $S_-EIN_+1=N_$ hält.

Fall 3 : Wenn Sie ein Sechseck $H$ zu $F$ hinzufügen, wobei $H$ und $F$ genau drei gemeinsame Kanten haben (beachten Sie, dass die drei Kanten benachbart sein müssen), dann haben wir in den neuen Polygonen $F'$ : $N_=N+1,quad S_=S_F+3,quad A_=A_F+2$ Wir sehen also, dass $S_-EIN_+1=N_$ hält.

Fall 4 : Wenn Sie ein Sechseck $H$ zu $F$ hinzufügen, wobei $H$ und $F$ genau vier gemeinsame Kanten haben (beachten Sie, dass die vier Kanten benachbart sein müssen), dann haben wir in den neuen Polygonen $F'$ $N_=N+1,quad S_=S_F+2,quad A_=A_F+1$ Wir sehen also, dass $S_-EIN_+1=N_$ hält.

Fall 5 : Wenn Sie ein Sechseck $H$ zu $F$ hinzufügen, wobei $H$ und $F$ genau fünf gemeinsame Kanten haben, dann haben wir in den neuen Polygonen $F'$ $N_=N+1,quad S_=S_F+1,quad A_=A_F$ Wir sehen also, dass $S_-EIN_+1=N_$ hält.


Treiber

Aktualisierte Treiber im Rahmen dieses RFC

  • PostGIS:
    • eine Ad-hoc-Unterstützung existiert bereits. Tabellen mit mehreren Geometrien werden derzeit als Layer mit dem Namen "table_name(geometry_col_name)" gemeldet (so viele Layer wie Geometriespalten). Dieses Verhalten wird geändert, sodass die Tabelle nur einmal als OGR-Layer gemeldet wird.
    • Schreibunterstützung für Tabellen mit mehreren Geometrien hinzufügen.
    • als einfache Veranschaulichung der neuen Funktionen aktualisiert.
    • aktualisiert, um mehrere Geometriefelder zu unterstützen (sowie andere Änderungen, die nichts mit diesem RFC zu tun haben)

    Andere Kandidatentreiber (Upgrade, die ursprünglich nicht von diesem RFC abgedeckt sind)

    • GML-Treiber: Derzeit wird nur eine Geometrie pro Feature gemeldet. Möglichkeit, dies durch manuelles Bearbeiten der .gfs-Datei zu ändern
    • SQLite-Treiber:
      • derzeit dasselbe Verhalten wie der aktuelle PostGIS-Treiber.
      • Sowohl der Treiber als auch der SQLite-Dialekt könnten aktualisiert werden, um Multi-Geometrie-Layer zu unterstützen.
      • Google Fusion Tables-Treiber: Derzeit wird nur die erste gefundene Geometriespalte verwendet. Möglichkeit, "table_name(geometry_column_name)" als Layernamen anzugeben, der an GetLayerByName?() übergeben wird.
      • VRT : Einige Gedanken sind erforderlich, um die Syntax zu finden, um mehrere Geometrien zu unterstützen.

      Betroffene XML-Syntax:

      . auf OGVRRTLayer-Elementebene:

      GeometryType?, LayerSRS, GeomField?, SrcRegion?, ExtentXMin/YMin/XMax/YMax,

      . auf OGRVRTWarpedLayer-Elementebene:

      Neues Element hinzufügen, um das Geometriefeld auszuwählen

      . auf OGRVRTUnionLayer-Elementebene:

      --> implementierte Post-RFC in GDAL 1.11

      • CSV : Derzeit Geometrien aus der Spalte "WKT" übernehmen. Erweiterbar, um mehrere Geometriespalten zu unterstützen. Der Aufwand lohnt sich nicht. Könnte mit dem erweiterten VRT-Treiber erfolgen.
      • WFS : Derzeit werden nur Single-Geometrie-Layer unterstützt. Der Standard erlaubt Multi-Geometrie. Würde zuerst GML-Treiberunterstützung benötigen.
      • Andere RDBMS-basierte Treiber: MySQL ?, MSSQLSpatial ? Oracle Spatial ?

      Bestimmen der Position eines Polygons innerhalb eines Kreises nur aus dem Winkel gegenüberliegender Seiten/Kanten.

      Ich habe ein einfaches konvexes unregelmäßiges Polygon (Achteck im Beispielbild) innerhalb eines Kreises (Kreis und Polygon sind nicht immer konzentrisch und berühren oder schneiden sich nie) und ich muss die Position des Polygons relativ zum Kreis bestimmen.

      Leider kenne ich nur drei grundlegende Dinge.

      1. Ich kenne den genauen Winkel zwischen den gegenüberliegenden Seiten des Polygons. Keine Seiten sind parallel.
      2. Wenn es auf den Kreis erweitert wird, bilden die Kanten/Seiten des Polygons einbeschriebene Winkel. Da ein Winkel zwei Polygonseiten ausmacht, gibt es immer halb so viele eingeschriebene Winkel wie Polygonseiten. Im Beispiel gibt es vier eingeschriebene Winkel, weil es ein Achteck ist.
      3. Die Scheitelpunkte jedes eingeschriebenen Winkels sind gleichmäßig um den Kreis verteilt.

      Meine Sorge ist, dass diese Art der Berechnung eine unendliche Anzahl von Iterationen und/oder mehrere Lösungen beinhalten könnte.

      Wenn ich die relativen Winkel (in der Zeichnung als "Unbekannt" bezeichnet) der eingeschriebenen Winkel wüsste, sollte das ausreichen, um alles andere zu bestimmen, oder? Auch wenn ich die "Mitte" des unregelmäßigen Polygons irgendwie annähern könnte.

      *Die unteren rechten Kanten im Beispiel treffen in einem so stumpfen Winkel aufeinander, dass sie wie eine Linie erscheinen, sorry. Es ist ein Achteck mit jedem eingeschriebenen Winkel, der zwei Seiten des Polygons bildet.


      Diese Informationen, die offensichtlich der alten Handbuchseite entnommen sind, geben Ihnen eine klare Vorstellung davon, was Sie beim Subsurfen erwartet.

      EDIT: Leider ist der Link zum alten Handbuch weg

      Es hat sich gelohnt, die ganze Seite zu lesen, speziell die Leistungsüberlegungen.

      Leistungsüberlegungen

      Höhere Unterteilungen bedeuten mehr Scheitelpunkte, und mehr Scheitelpunkte bedeuten, dass mehr Speicher verwendet wird (sowohl Videospeicher für die Anzeige als auch System-RAM für das Rendern). Blender könnte möglicherweise abstürzen oder hängen bleiben, wenn Sie nicht über genügend Arbeitsspeicher verfügen.

      Bei Verwendung hoher Unterteilungsstufen mit einer Grafikkarte mit einer geringen Gesamtmenge an Vram verschwinden einige Teile der Geometrie visuell. Ihr Mesh ist tatsächlich in Ordnung, da das Rendering mit Ihren Objektdaten generiert wird (auch wenn es von Ihrer Grafikkarte nicht angezeigt werden kann).

      Die Anzahl der Flächen (Polygone) wird im Info-Header oben.

      Nach dem Hinzufügen von a Subsurf-Modifikator es hat 96 Gesichter (2 Unterteilungen:

      In einer komplexen Szene mit mehreren Objekten müssten Sie wechseln zu Bearbeitungsmodus oder verschieben Sie das Objekt auf eine nicht verwendete Ebene M, um nur die Anzahl der Gesichter für ein bestimmtes Objekt zu sehen.

      Bevor Sie den Modifikator anwenden, ist es auch eine gute Idee, zu zu wechselnDrahtmodell Anzeigemodus, um einen Eindruck davon zu bekommen, wie dicht das Netz tatsächlich ist.

      Die Unterteilung teilt eine Fläche in vier Flächen (pro Ebene) auf, wie dies bei der Netzunterteilung der Fall wäre. Hier ein Beispiel mit Algorithmus Einfach weil es offensichtlicher erscheint.

      Die grobe Regel, die sich aus den obigen Informationen ergibt (ohne die Arbeit zu studieren) ist

      es deckt keine Dreiecke und n-Ecke ab. Für eine genauere Beschreibung siehe:

      Es bietet Formeln, die auf der Anzahl der Vetices basieren, die genauer zu sein scheinen.


      Datensatz veröffentlicht 2011-03-09
      Zuletzt geändert aufnehmen 2021-06-25
      Ressourcenstatus weiterGehen

      Objektbeschreibung

      Objektname: WHSE_FOREST_TENURE.FTEN_RECREATION_POLY_SVW

      Kurzer Name: FTN_REC_PL
      Bemerkungen: Die räumliche Darstellung eines Freizeit-Features. Dies kann entweder ein Erholungsgebiet, ein Erholungsgebiet oder ein interpretativer Wald sein.


      Schauen Sie sich TileAreas in ComputationalGeometry an:

      EDIT: Warte, du wolltest auch Perimeter.

      ZWEITE BEARBEITUNG: Anzahl der Seiten

      Wenn Sie das BoundedDiagram vieler Punkte immer wieder verwenden, sollten Sie es wahrscheinlich speichern, anstatt jedes Mal neu zu berechnen, wie ich es tue.

      Es ist über ein Jahr her, aber seit v10 einige nette Funktionen eingeführt haben, um dies elegant zu tun, lassen Sie uns diese Frage noch einmal aufgreifen:

      Wir generieren einige Punkte und erhalten ihr Voronoi-Diagramm mit VoronoiMesh

      Nun zu den Bereichen der Zellen:

      Bearbeiten: Eine sauberere Methode zur Berechnung der Flächen besteht darin, Folgendes zu tun:

      Wir können überprüfen, dass die Gesamtfläche tatsächlich 16 beträgt (die Fläche des beschränkten Voronoi-Diagramms $4^2$).

      Um die Perimeter zu berechnen, verwenden wir RegionMeasure , konvertieren die Polygon-Primitive in Line-Primitive und achten darauf, die Linien wieder zu verbinden.

      Schließlich machen wir für die Anzahl der Seiten jeder Zelle einfach:

      Die von VoronoiMesh erstellten MeshRegion-Objekte haben Eigenschaften, die für diesen Zweck nützlich sind. Hier ist das Beispielnetz von @RunnyKine:

      Die MeshRegion-Eigenschaften verwenden Flächen-IDs, die jeder Fläche zugewiesen wurden. Leider stimmen die Gesichtsbeschriftungen nicht mit den internen Gesichts-IDs überein. Hier ist also eine Modifikation des Voronoi-Netzes, das die Gesichts-IDs als Beschriftungen verwendet (hier verwende ich die Eigenschaft "Faces" eines MeshRegion-Objekts):

      Beachten Sie, wie sich die Beschriftungen von denen unterscheiden, die in der Visualisierung von @RunnyKine verwendet werden.

      Um nun den Umfang jeder Zelle zu erhalten, können wir sowohl "FaceEdgeConnectivity" als auch "EdgeLengths" verwenden:

      <1 ->3.99709, 2 -> 2.7707, 3 -> 3.61356, 4 -> 3.88435, 5 -> 3.40604, 6 -> 4.40972, 7 -> 4.1388, 8 -> 4.05183, 9 -> 2.60374, 10 -> 2.75359, 11 -> 3.55026, 12 -> 3.63583, 13 -> 3.18751, 14 -> 3.21415, 15 -> 4.20549, 16 -> 2.08804, 17 -> 3.3514, 18 -> 5.58528, 19 -> 5.40562, 20 -> 4.3344>

      Für den Bereich verwenden wir "FaceAreas":

      <1 ->1.00297, 2 -> 0.268352, 3 -> 0.73707, 4 -> 0.834388, 5 -> 0.665234, 6 -> 1.23476, 7 -> 0.974388, 8 -> 0.938105, 9 -> 0.402544, 10 -> 0.363854, 11 -> 0.59353, 12 -> 0.759838, 13 -> 0.55102, 14 -> 0.367406, 15 -> 0.957965, 16 -> 0.210096, 17 -> 0.602978, 18 -> 1.99269, 19 -> 1.44529, 20 -> 1.09752>

      Und schließlich zur Kantenzählung:

      <1 ->7, 2 -> 4, 3 -> 6, 4 -> 5, 5 -> 8, 6 -> 5, 7 -> 5, 8 -> 8, 9 -> 5, 10 -> 4, 11 -> 4, 12 -> 5, 13 -> 4, 14 -> 5, 15 -> 6, 16 -> 4, 17 -> 5, 18 -> 6, 19 -> 5, 20 -> 5>