[Gdal-dev] Read/Write Oracle Spatial

Hallgren Johan E jhhal at wmdata.com
Thu Oct 27 04:24:24 EDT 2005


Thanks for all the assistance.

My SetFeature problem was probably caused by the bad geometry handling in the code. It's solved now but there is still two functions a have isolated but problems remain. 

When updating a field I use a function SetField and it just don't work. It will crash on that call. 

The other function is DeleteFeature. The problem is the same, it just don't work and crash on that call. 

In both cases I know that record is there and the actual layer have the standard OGR_FID-keycolumn.

Any assistance is appreciated and my next step is to file it as a bug in the SWIG/C# binding.

Below is the code I have used.

Best regards
Johan

Geometry code that works.
-----------------------------------
OGR.ogr.RegisterAll();

OGR.Driver d = OGR.ogr.GetDriverByName("OCI");
OGR.DataSource ds = d.Open(@"OCI:wmgis/wmgis01 at WMSI1394", 0);

int iFID = Convert.ToInt32(txtFID.Text);
OGR.Layer l = ds.GetLayerByName("granser");
// Read the feature;
OGR.Feature f = l.GetFeature(iFID);

OGR.Geometry g = f.GetGeometryRef();
double x = g.GetX(0);
double y = g.GetY(0);
double z = g.GetZ(0);
x += 1.0;
y += 1.0;
try
{
	l.StartTransaction();

	// Modify the reference
	g.SetPoint(0, x, y, z);

	l.SetFeature(f);
	l.CommitTransaction();
}
catch (Exception ex)
{
	MessageBox.Show(ex.Message);
	l.RollbackTransaction();
}
-----------------------------------

SetField-code

-----------------------------------
OGR.ogr.RegisterAll();

OGR.Driver d = OGR.ogr.GetDriverByName("OCI");
OGR.DataSource ds = d.Open(@"OCI:wmgis/wmgis01 at WMSI1394", 0);

int iFID = Convert.ToInt32(txtFID.Text);
OGR.Layer l = ds.GetLayerByName("granser");
// Read the feature;
OGR.Feature f = l.GetFeature(iFID);

try
{
	l.StartTransaction();

	// Modify the reference
	// HERE IT FAILS...
	f.SetField("NUM", "3");

	l.SetFeature(f);
	l.CommitTransaction();
}
catch (Exception ex)
{
	l.RollbackTransaction();
	MessageBox.Show(ex.Message);
}
-----------------------------------

DeleteFeature code

-----------------------------------
OGR.ogr.RegisterAll();

OGR.Driver d = OGR.ogr.GetDriverByName("OCI");
OGR.DataSource ds = d.Open(@"OCI:wmgis/wmgis01 at WMSI1394", 0);

int iFID = Convert.ToInt32(txtFID.Text);
OGR.Layer l = ds.GetLayerByName("granser");
try
{
	l.StartTransaction();
	l.DeleteFeature(iFID);
	l.CommitTransaction();
}
catch (Exception ex)
{
	l.RollbackTransaction();
	MessageBox.Show(ex.Message);
}
-----------------------------------

___________________________________


Johan Hallgren
WM-data


Pelle Bergs backe 3
Box 1938, 791 19 Falun
Tel: 023-844 65 (int: +46-2384465)
Mobil: 070-588 44 28 (int: +46-705884428)
johan.e.hallgren at wmdata.com
http://www.wmdata.se


-----Ursprungligt meddelande-----
Från: fwarmerdam at gmail.com [mailto:fwarmerdam at gmail.com] För Frank Warmerdam
Skickat: den 26 oktober 2005 18:02
Till: Hallgren Johan E
Kopia: gdal-dev at lists.maptools.org
Ämne: Re: [Gdal-dev] Read/Write Oracle Spatial

On 10/26/05, Hallgren Johan E <jhhal at wmdata.com> wrote:
> OGR.Driver d = OGR.ogr.GetDriverByName("OCI");
> OGR.DataSource ds = d.Open(@"OCI:wmgis/wmgis01 at WMSI1394", 1);
>
> GDAL.gdal.SetConfigOption("OGR_FID","OBJECTID");

Johan,

You need to call SetConfigOption() before opening the datasource
as it alters the decisions made as the layers are scanned during
the open.

> I tried to do add a column OGR_FID (primary key) to the table but in that case it failed on the SetFeature with no meaningful error message. Now the actual record was gone so my guess is that the function removes the record and when adding a new it fails (can it be something with the OGR_FID not being properly updated?).

SetFeature does indeed operate by deleting the existing row and re-creating
it.   You could do a StartTransaction() and Commit() or Rollback() after
the SetFeature() if you want better error handling.  It really ought to do
this internally if there is no active transaction.

> Finally, is it the right way to use SetFeature when updating a record?
>
> I hope you have time to answer my questions.

I think you are doing things right, and I am not sure why it isn't
working; however, I don't think SetFeature() is used often.  I see
it is not used in the ogr_oci.py test script for the OCI provider.  It
may just be broken.

Unfortunately, while I have time to answer this question, I don't
have time to reboot into win32, and fiddle around to see what is
going wrong today.  You might want to file a bug report.

For now it is hard to say if you are encountering some limitation
of the c# bindings or ogr.

... one extra review of your code ...

Actually, now I see you are doing things in a transaction, but
committing it even if the SetFeature() fails.

Also, more seriously, I see you are fetching a reference to the
feature geometry modifying it and then calling SetGeometryDirectly().
The problem with this is that GetGeometryRef() returns a pointer to
the internal feature geometry.  So you are modifying it directly on
the feature, and then when you do the SetGeometryDirectly() it
will delete the old geometry and try to set the new one.  But the
new one is really the old one, now deleted.  So you should skip
the SetGeometryDirectly() step ... or .. clone the result that comes
back from GetGeometryRef().

Best regards,
--
---------------------------------------+--------------------------------------
I set the clouds in motion - turn up   | Frank Warmerdam, warmerdam at pobox.com
light and sound - activate the windows | http://pobox.com/~warmerdam
and watch the world go round - Rush    | Geospatial Programmer for Rent




More information about the Gdal-dev mailing list