Mittwoch, 30. April 2014

Kleines Experiment mit POINTONSURFACE

Im Package SDO_GEOM gibt es die Funktion SDO_POINTONSURFACE. Diese ermittelt einen Punkt, der räumlich auf der Oberfläche eines Polygons liegen soll.
Aber wie wird dieser Punkt ermittelt? Welches Ergebnis ist zu erwarten?

Um diese Fragen zu beantworten, habe ich mir eine Prozedur geschrieben, welche diese Funktion mehrfach aufruft und die zurückgegebenen Punktgeometrien in eine Tabelle schreibt.
drop table points purge;

create table points (
  id number,
  geom sdo_geometry,
  constraint points_pk primary key (id) enable);

declare
  type t_points is table of points%ROWTYPE;
  l_tab t_points := t_points();
  l_size number := 10;
  l_lastid number;
  l_pointonsurface sdo_geometry;
  l_surface sdo_geometry;

begin
  -- Fetch last id from points table
  select nvl(max(id),1) + 1 into l_lastid from points;
  select s.geom into l_surface from us_state s where s.name = 'California';

  -- Populate collection
  for i in 1 .. l_size LOOP
    -- Call POINTONSURFACE
    select sdo_geom.sdo_pointonsurface(l_surface, 0.05) into l_pointonsurface from dual;
    l_tab.extend;
    l_tab(l_tab.last).id := l_lastid;
    l_tab(l_tab.last).geom := l_pointonsurface;
    l_lastid := l_lastid + 1;

  end loop;
 
 -- Ingest table with points
  forall i in l_tab.first .. l_tab.last
    insert /*+ APPEND_VALUES */ into points values l_tab(i);
  commit; 
end;
/
Schaue ich mir die 10 Sätze in der Tabelle POINTS an, finde ich immer die gleichen Punktgeometrien: Lon=-123.00111 und Lat=37.772053.
select p.geom.sdo_point.x lon, p.geom.sdo_point.y lat from points p;
Wer also die Idee hat, diese Funktion zu verwenden, um eine Tabelle mit zufälligen Punktgeometrien zu befüllen, muss einen anderen Lösungsansatz wählen. (Einen solchen Lösungsansatz habe ich in diesem Blog-Posting vorgestellt.)

Aber was ist denn jetzt das "Geheimnis" hinter SDO_POINTONSURFACE?
Die Antwort ist (einfach):
Es wird der 1. Stützpunkt der Flächengeometrie zurückgegeben, die als Eingabeparameter übergeben wird. (Das ist in meinem Beispiel der Bundesstaat Kalifornien.)
select t.x, t.y, t.id
from us_state s, table(sdo_util.getvertices(s.geom)) t
where s.name = 'California' and t.id = 1;


Keine Kommentare:

Kommentar veröffentlichen