[Gfoss] cml2shp.py

Bud P. Bruegger bud a comune.grosseto.it
Ven 14 Dic 2007 13:02:47 CET


Ciao a tutti,

Ho finalmente messo mano su un file CXF e uno CML, tutte e due
disponibile ugualmente dal portale per comuni del catasto.  Ho capito
dal file (e non l'avevo capito dalla spec) che l'attributo e' gia'
logicamente associato alla geometria.   Cosi il parsing e' molto piu'
facile che pensavo.  

Allora mi ho messo a scrivere un piccolo parser per CML che e' xml e
cosi piu' facile che quello di CXF.  

La versione attuale prende solo Bordi (incl. particelle e fabbricati).
Fin ora lo mette in una rappresentazione in memoria.  Il prossimo passo
sara' di scrivere su un shape file usando la shapelib di python.  Spero
di mandare una versione che include questo piu' tardi oggi.

Commenti molto benvenuti

saluti
-b



#######################################################################
## =======
## cml2shp
## =======
##
## Converts a subset of content from a file in
## Cadastral Markup Language (CML) [1] to a
## shape file
##
## [1] CML spec:
## http://www.agenziaterritorio.it/servizi/comunieistituzioni/..
## ..fornitura_dati_catastali/specifica%20tecnica%20CML.doc
##
## Copyright:  Comune di Grosseto
## Author:     Bud P. Bruegger <bud at comune.grosseto.it>
## License:    GPL (any version)
#######################################################################

import operator

import shapelib
import elementtree.ElementTree as ET

version = "0.1 14/12/2007"

#fileName = "testdata/E202_000100.CMF"
fileName = "testdata/vertisola.CMF"

class Feature(object):
    "a simple in memory rep of a feature"
    def __init__(self, bordoType, mappaID, particellaID, valenza,
esterconf, geom): self.bordoType = bordoType
        self.mappaID = mappaID
        self.particellaID = particellaID
        self.valenza = valenza
        self.esterconf = esterconf
        self.geom = geom
        #geometry is represented by a list of rings,
        #where every ring is a list of x/y tuples
        #the first ring is the main one,
        #the others are islands

#-------------------------------------
def parseFabbriPart(codbo):
    "parses a codbo of a fabbricato or particella"
    bordoType = "PARTICELLA"
    particellaID = codbo
    if codbo[-1] == '+':
        bordoType = "FABBRICATO"
        particellaID = codbo[:-1]
    return bordoType, particellaID
        
def codboParse(codbo, mapName):
    "parses a codbo"
    #returns: bordoType, particellaID
    codbo = codbo.strip()
    mappaID = mapName
    if codbo == mapName:
        bordoType = "MAPPA"
        particellaID = ""
    elif codbo == "STRADA":
        bordoType = "STRADA"
        particellaID = ""
    elif codbo == "ACQUA":
        bordoType = "ACQUA"
        particellaID = ""
    else:
        bordoType, particellaID = parseFabbriPart(codbo)
    return bordoType, particellaID

def vertConsume(nVerts, vertList):
    return vertList[:nVerts], vertList[nVerts:]

def coordParse(nVert, vertIsolaList, coordStr):
    noIsolaVerts = reduce(operator.add, vertIsolaList, 0)
    vertexList = [subStr.split(',') for subStr in coordStr.split()]
    geom = []
    mainRing, remainingVerts = vertConsume((nVert - noIsolaVerts),
vertexList) geom.append(mainRing)
    for noIslandVerts in vertIsolaList:
        islandRing, remainingVerts = vertConsume(noIslandVerts,
remainingVerts) geom.append(islandRing)
    return geom


#-- main parsing ---------------------
mapTree = ET.parse(fileName)
mapRoot = mapTree.getroot()
mapID = mapRoot.find("INFOMAPPA").get("nome")
featureList = []

#-- process BORDO elements ------------------
for border in mapRoot.getiterator("BORDO"):
    bordoType, particellaID = codboParse(border.get("codbo"), mapID)
    valenza = border.get("valenza")
    esterconf = border.get("esterconf")
    gbordo = border.find("GBORDO")
    #nIsole = gbordo.get("n.isole")
    nVert = int(gbordo.get("n.vert"))
    vertIsolaList = map(int, [i.text for i in gbordo.getiterator
("VERTISOLA")]) coordStr = gbordo.find("COORD").text
    geom = coordParse(nVert, vertIsolaList, coordStr)
    featureList.append(Feature(bordoType, mapID, particellaID,
                               valenza, esterconf, geom))


-- 
Bud P. Bruegger, Ph.D.          +39-0564-488577 (voice),  -21139 (fax) 
   European Chair, Global Collaboration Forum on eID
   Chair, Porvoo Subgroup on collab. govs/operating systems
   Leader of the Permanent eID Status Observatory (PESO) project
Servizio Elaborazione Dati       e-mail:  bud at comune.grosseto.it
Comune di Grosseto               jabber:  bud at jabber.no
Via Ginori, 43                   http://www.comune.grosseto.it/
58100 Grosseto (Tuscany, Italy)
http://www.comune.grosseto.it/interopEID/



Maggiori informazioni sulla lista Gfoss