Version 0 of tclshapefile

Updated 2012-01-02 16:30:09 by joheid

Tclshapefile is a tcl-only package to read esri shapefiles (well at least points, polylines and polygones). It reads both the geometry (.shp) files and the attribute (.dbf) file. Data are returned as dicts. It uses the specific reader components shpreader and dbfreader.


 # $Id: tclshapefile.tcl,v 1.1 2012/01/02 16:18:03 joheid Exp $
 # 
 # package to read esri shapefiles
 # uses shpreader and dbfreader as components
 # (C) Joachim Heidemeier 2011
 # published under the same license als Tcl
 # 
 # methods
 # readShape
 # readCoords -> delegated
 # readAttributes -> delegated
 # getCoords -> delegated
 # getAttributes -> delegated
 # dbfInfo -> delegatd
 # shpInfo  -> delegated 
 # getRecord
 # readProjection 
 # 

 package require snit
 # specific reader packages
 package require shpreader.tcl
 package require dbfreader.tcl
 #
 # 
 #
 #
 #
 # 
 package provide shapefile 0.5
 snit::type shapefile {
 #
 # components
 # 
 component dbfReader
 delegate option -encoding to dbfReader
 delegate method attributes to dbfReader
 delegate method readAttributes to dbfReader as readData
 delegate method getAttributes to dbfReader as data 
 delegate method dbfInfo to dbfReader as dbfInfo
 #
 component shpReader
 delegate option -bbox to shpReader
 delegate option -shapetype to shpReader
 delegate option -nrecords to shpReader
 delegate method readCoords to shpReader as readData
 delegate method getCoords to shpReader as coords
 delegate method shpInfo to shpReader 
 #
 # options
 # 
 #  
 option -filename -validatemethod CheckFile -configuremethod ShapeFileName
 # 
 # for use as component
 # option -partof 
 # 
 option -projection none
 #
 # variablen
 # 
 variable status ;# interneral status
 set status(shpcheck) 0
 set status(dbfcheck) 0
 set status(projection) 0
 set status(projectionfile) {}    
 #
 # validatemethods
 #
 # checks whether a shp, shx and dbf and proj file is available
 # error if no shp &  dbf
 # 
 method CheckFile {option value}  { 

    set fn [file rootname $value]
    if {!([file exists $fn.shp] && [file exists $fn.shx] && [file exists $fn.dbf])} {
        error "$fn ist kein gültiger shapefile"
    } else {
        set status(shpcheck) 1
        set status(dbfcheck) 1
        }
    if {[file exists $fn.prj]} {
            set status(projection) 1 
        }
 }
 #
 # configuremethods
 # 
 method ShapeFileName {option value} {
        set f  [file rootname $value]
        set options(-filename) $f
        set status(projectionfile) ${f}.prj
        $dbfReader configure -filename ${f}.dbf
        $shpReader configure -filename ${f}.shp
 return
 }
 #
 #
 constructor {args} {
    install dbfReader using dbasefile  %AUTO% -partof $self
    install shpReader using shpfile %AUTO% -partof $self
    $self configurelist $args
 }
 destructor  {
        catch {$dbRreader destroy}
        catch {$shpReader destroy}
 }    
 #
 # read the proj file
 # public methods
 method readProjection {} {
    if {$status(projection)} {
        set option(-projection) [read [open $status(projectionfile) r]]
    }
 }
 #
 # 
 # opens shp, dbf and proj, set options
 # reads all data
 #
 method readShape {} {
        $shpReader readData
        $dbfReader readData
        if {[$shpReader cget -nrecords] != [lindex [$dbfReader dbfInfo] 0]} {
            error {different number of records in shp and dbf File}
        }
        $self readProjection
    }
 method getRow {recnr} {
    set x [dict create]
    if {[string is integer $recnr] && $recnr <= [$shpReader cget -nrecords]} {
        dict append x coords [dict get [$shpReader coords $recnr] $recnr]
        dict append x attributes [dict get [$dbfReader data  $recnr] $recnr]
        } else {error "not existing record requested"}
    return $x
 }
 }
 #
 #
 if {0} {
 shapefile s1 -filename [tk_getOpenFile]
 s1 readShape
 set c [s1 getCoords 1]
 set a [s1 getAttributes 1]
 set x [s1 getRow 1]
 set t [s1 cget -shapetype]
 }

---