229 |
|
|
230 |
def get_default_static_data_db(self): |
def get_default_static_data_db(self): |
231 |
dbname = "PostGISStaticTests" |
dbname = "PostGISStaticTests" |
232 |
tables = [("landmarks", os.path.join("..", "Data", "iceland", |
tables = [ |
233 |
"cultural_landmark-point.shp")), |
# Direct copies of the shapefiles. The shapeids are exactly |
234 |
("political", os.path.join("..", "Data", "iceland", |
# the same. |
235 |
|
("landmarks", os.path.join("..", "Data", "iceland", |
236 |
|
"cultural_landmark-point.shp"), |
237 |
|
[("gid_offset", 1000)]), |
238 |
|
("political", os.path.join("..", "Data", "iceland", |
239 |
"political.shp")), |
"political.shp")), |
240 |
|
("roads", os.path.join("..", "Data", "iceland", |
241 |
|
"roads-line.shp")), |
242 |
|
|
243 |
# The polygon data as a MULTIPOLYGON geometry type |
# The polygon data as a MULTIPOLYGON geometry type |
244 |
("political_multi", os.path.join("..", "Data", "iceland", |
("political_multi", os.path.join("..", "Data", "iceland", |
245 |
"political.shp"), |
"political.shp"), |
246 |
"MULTIPOLYGON"), |
[("force_wkt_type", "MULTIPOLYGON")]), |
247 |
|
] |
|
("roads", os.path.join("..", "Data", "iceland", |
|
|
"roads-line.shp"))] |
|
248 |
return self.get_static_data_db(dbname, tables) |
return self.get_static_data_db(dbname, tables) |
249 |
|
|
250 |
def connection_params(self, user): |
def connection_params(self, user): |
324 |
"""A PostGIS database in a PostgreSQLServer""" |
"""A PostGIS database in a PostgreSQLServer""" |
325 |
|
|
326 |
def __init__(self, server, postgis_sql, dbname, tables = None): |
def __init__(self, server, postgis_sql, dbname, tables = None): |
327 |
|
"""Initialize the PostGISDatabase |
328 |
|
|
329 |
|
Parameters: |
330 |
|
|
331 |
|
server -- The PostgreSQLServer instance containing the |
332 |
|
database |
333 |
|
|
334 |
|
postgis_sql -- Filename of the postgis.sql file with the |
335 |
|
postgis initialization code |
336 |
|
|
337 |
|
dbname -- The name of the database |
338 |
|
|
339 |
|
tables -- Optional description of tables to create in the |
340 |
|
new database. If given it should be a list of |
341 |
|
(tablename, shapefilename) pairs meaning that a table |
342 |
|
tablename will be created with the contents of the given |
343 |
|
shapefile or (tablename, shapefilename, extraargs) |
344 |
|
triples. The extraargs should be a list of key, value |
345 |
|
pairs to use as keyword arguments to upload_shapefile. |
346 |
|
""" |
347 |
self.server = server |
self.server = server |
348 |
self.postgis_sql = postgis_sql |
self.postgis_sql = postgis_sql |
349 |
self.dbname = dbname |
self.dbname = dbname |
375 |
"GRANT SELECT ON geometry_columns TO PUBLIC;") |
"GRANT SELECT ON geometry_columns TO PUBLIC;") |
376 |
|
|
377 |
if self.tables is not None: |
if self.tables is not None: |
378 |
for info in self.tables: |
def unpack(item): |
379 |
|
extra = {"force_wkt_type": None, "gid_offset": 0} |
380 |
if len(info) == 2: |
if len(info) == 2: |
381 |
tablename, shapefile = info |
tablename, shapefile = info |
|
wkt_type = None |
|
382 |
else: |
else: |
383 |
tablename, shapefile, wkt_type = info |
tablename, shapefile, kw = info |
384 |
upload_shapefile(shapefile, self, tablename, |
for key, val in kw: |
385 |
force_wkt_type = wkt_type) |
extra[key] = val |
386 |
|
return tablename, shapefile, extra |
387 |
|
|
388 |
|
for info in self.tables: |
389 |
|
tablename, shapefile, kw = unpack(info) |
390 |
|
upload_shapefile(shapefile, self, tablename, **kw) |
391 |
|
|
392 |
def has_data(self, tables): |
def has_data(self, tables): |
393 |
return self.tables == tables |
return self.tables == tables |
449 |
The name of the postgis_sql file is determined by find_postgis_sql() |
The name of the postgis_sql file is determined by find_postgis_sql() |
450 |
- psycopg can be imported successfully. |
- psycopg can be imported successfully. |
451 |
""" |
""" |
452 |
|
# run_command currently uses Popen4 which is not available under |
453 |
|
# Windows, for example. |
454 |
|
if not hasattr(popen2, "Popen4"): |
455 |
|
return "Can't run PostGIS test because popen2.Popen4 does not exist" |
456 |
|
|
457 |
try: |
try: |
458 |
run_command(["pg_ctl", "--help"], None) |
run_command(["pg_ctl", "--help"], None) |
459 |
except RuntimeError: |
except RuntimeError: |
486 |
if _cannot_run_postgis_tests: |
if _cannot_run_postgis_tests: |
487 |
raise support.SkipTest(_cannot_run_postgis_tests) |
raise support.SkipTest(_cannot_run_postgis_tests) |
488 |
|
|
489 |
|
def skip_if_addgeometrycolumn_does_not_use_quote_ident(): |
490 |
|
"""Skip a test if the AddGeometryColumn function doesn't use quote_ident |
491 |
|
|
492 |
|
If the AddGeometryColumn function doesn't use quote_ident it doesn't |
493 |
|
support unusual table or column names properly, that is, it will |
494 |
|
fail with errors for names that contain spaces or double quotes. |
495 |
|
|
496 |
|
The test performed by this function is a bit simplistic because it |
497 |
|
only tests whether the string 'quote_ident' occurs anywhere in the |
498 |
|
postgis.sql file. This will hopefully works because when this was |
499 |
|
fixed in postgis CVS AddGeometryColumn was the first function to use |
500 |
|
quote_ident. |
501 |
|
""" |
502 |
|
f = file(find_postgis_sql()) |
503 |
|
content = f.read() |
504 |
|
f.close() |
505 |
|
if content.find("quote_ident") < 0: |
506 |
|
raise support.SkipTest("AddGeometryColumn doesn't use quote_ident") |
507 |
|
|
508 |
def coords_to_point(coords): |
def coords_to_point(coords): |
509 |
"""Return string with a WKT representation of the point in coords""" |
"""Return string with a WKT representation of the point in coords""" |
510 |
x, y = coords[0] |
x, y = coords[0] |
538 |
"MULTIPOLYGON": coords_to_multipolygon, |
"MULTIPOLYGON": coords_to_multipolygon, |
539 |
} |
} |
540 |
|
|
541 |
def upload_shapefile(filename, db, tablename, force_wkt_type = None): |
def upload_shapefile(filename, db, tablename, force_wkt_type = None, |
542 |
|
gid_offset = 0): |
543 |
|
"""Upload a shapefile into a new database table |
544 |
|
|
545 |
|
Parameters: |
546 |
|
|
547 |
|
filename -- The name of the shapefile |
548 |
|
|
549 |
|
db -- The PostGISDatabase instance representing the database |
550 |
|
|
551 |
|
tablename -- The name of the table to create and into which the data |
552 |
|
is to be inserted |
553 |
|
|
554 |
|
force_wkt_type -- If given the real WKT geometry type to use instead |
555 |
|
of the default that would be chosen based on the type of |
556 |
|
the shapefile |
557 |
|
|
558 |
|
gid_offset -- A number to add to the shapeid to get the value for |
559 |
|
the gid column (default 0) |
560 |
|
""" |
561 |
import dbflib, shapelib |
import dbflib, shapelib |
562 |
|
|
563 |
# We build this map here because we need shapelib which can only be |
# We build this map here because we need shapelib which can only be |
610 |
for i in range(numshapes): |
for i in range(numshapes): |
611 |
data = dbf.read_record(i) |
data = dbf.read_record(i) |
612 |
data["tablename"] = tablename |
data["tablename"] = tablename |
613 |
data["gid"] = i |
data["gid"] = i + gid_offset |
614 |
data["the_geom"] = convert(shp.read_object(i).vertices()) |
data["the_geom"] = convert(shp.read_object(i).vertices()) |
615 |
#print insert % data |
#print insert % data |
616 |
cursor.execute(insert, data) |
cursor.execute(insert, data) |