[postgis-users] ESRI Shapes from database

Lee Keel lee.keel at uai.com
Tue Oct 16 07:49:25 PDT 2007


I am trying to get ESRI multipolygon shapes into PostGIS without going to a
shape file first.  I have several reasons that I can't go to shape files
first, but I have the shape data in a Sql Server 2000 database.  I was
parsing the ESRI shape in C# code and then pushing the string to the
database.  The problem that I am having doing this is that I get an 'Out of
memory' error on the string for the text of some of my shapes.  I have
traced that down to a limit by MS on the size of a string and the size of
stringbuilder (2GB).  (FYI my machine has 8GB, so it is not my machine that
was running out of memory.)  So, my next thought was a stored procedure
where I just passed the binary in and parsed it on the server.  I have
listed the stored procedure that I am using to convert the ESRI shape into a
WKT so that I can then convert to WKB.  My problem is that I can find a way
to convert parts of a bytea into a float.

My function:


CREATE OR REPLACE FUNCTION esribytea2text(bytea)
  RETURNS text AS
$BODY$
DECLARE
	esri_shape alias for $1;
	
	xCoord numeric;
	yCoord numeric;

	num_parts int;
	num_points int ;
	first_pt_idx int ;
	next_pt_idx int := 0 ;
	idx int := 48;
	pt_idx int ;
				
	first_pt varchar;
	sb text ;

	isFirstPt bool := true ;
BEGIN
	num_parts := get_byte(esri_shape::bytea, 36)::int ;
	num_points := get_byte(esri_shape::bytea, 40)::int ;
	first_pt_idx := 44 + (4 * num_parts) ;

	pt_idx := get_byte(esri_shape::bytea, idx)::int ;

	FOR cnt IN first_pt_idx..length(esri_shape)-16 BY 16 LOOP
		--xCoord := decode(substring(esri_shape from cnt for 8),
float);		--PROBLEM
		xCoord := (select encode(esri_shape::bytea,'hex')::float);
--PROBLEM
		yCoord := get_byte(esri_shape, cnt + 8)::float;
--PROBLEM
		
		insert into tempdata(func, txtdata)
values('esribytea2text:x', xCoord);
		insert into tempdata(func, txtdata)
values('esribytea2text:y', yCoord);

		IF char_length(sb) = 0 THEN
			sb := sb || '(' || xCoord || ' ' || yCoord;
		ELSE
			IF isFirstPt THEN
				sb := sb || ', (' || xCoord || ' ' ||
yCoord;
			ELSE
				sb := sb || ', ' || xCoord || ' ' || yCoord;
			END IF;
		END IF;

		IF isFirstPt THEN
			isFirstPt := false ;
			first_pt :=  xCoord || ' ' || yCoord; 
		END IF;

		IF (num_parts > 1 AND pt_idx = next_pt_idx AND idx <
first_pt_idx) THEN
			IF (char_length(sb)>0 AND char_length(first_pt)>0)
THEN
				sb := sb || ', ' + first_pt + ')';
				isFirstPt := true ;
			END IF;

			idx := idx + 4 ;
			pt_idx := get_byte(esri_shape::bytea, idx)::int ;
		END IF;

		next_pt_idx := next_pt_idx + 1 ;
	END LOOP;

	IF (char_length(sb)>0 AND char_length(first_pt)>0) THEN
		sb := sb || ', ' || first_pt || ')';
		isFirstPt := true ;
	END IF;

	insert into tempdata(func, txtdata) values('esribytea2text', sb);

	return 'MULTIPOLYGON((' || sb || '))';
END;
$BODY$
  LANGUAGE 'plpgsql' VOLATILE;
ALTER FUNCTION esribytea2text(bytea) OWNER TO postgres;



The lines that are marked with '--PROBLEM' are where my problem exists.
What I am trying to do here is take 8 bytes from the bytea and cast them to
a float.  The errors that I am getting are:

For:
xCoord := substring(arrByte from cnt for 8)::float8;
Error:
ERROR: 42846: cannot cast type bytea to double precision

For:
xCoord := (select encode(esri_shape::bytea,'escape')::float)
Error:
invalid input syntax for type double precision

For:
yCoord := get_byte(esri_shape, cnt + 8)::float;
Error:
It only returns the single byte (as I would expect), not all 8 bytes for the
float

The table 'tempdata' is just a table used for dumping results (Schema
Below).  The reason that I had to do this was because I was using get_byte
and thought it was working, but it really wasn't.  

CREATE TABLE tempdata
(
  id serial NOT NULL,
  func text,
  txtdata text
) 
WITHOUT OIDS;
ALTER TABLE tempdata OWNER TO postgres;


I am very close to getting this working but have run into this last road
block.  I would appreciate any help that anyone can provide as I do have a
client waiting on a solution.

Thanks in advance,
Lee Keel



This email and any files transmitted with it are confidential and intended solely for the use of the individual or entity to whom they are addressed. If you have received this email in error please notify the sender. This message contains confidential information and is intended only for the individual named. If you are not the named addressee you should not disseminate, distribute or copy this e-mail.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/postgis-users/attachments/20071016/a5e1e97a/attachment.html>


More information about the postgis-users mailing list