Desejo criar programaticamente um arquivo GeoJSON usando polígonos de um shapefile, mas adicionando atributos do meu próprio aplicativo.
Isso é feito facilmente para um shapefile:
def create_data_dayer(self,varlist, data):
"""
Creates a new shape to contain data about nodes.
varlist is the list of fields names associated with
the nodes.
data is a list of lists whose first element is the geocode
and the remaining elements are values of the fields, in the
same order as they appear in varlist.
"""
if os.path.exists(os.path.join(self.outdir,'Data.shp')):
os.remove(os.path.join(self.outdir,'Data.shp'))
os.remove(os.path.join(self.outdir,'Data.shx'))
os.remove(os.path.join(self.outdir,'Data.dbf'))
# Creates a new shape file to hold the data
if not self.datasource:
dsd = self.driver.CreateDataSource(os.path.join(self.outdir,'Data.shp'))
self.datasource = dsd
dl = dsd.CreateLayer("sim_results",geom_type=ogr.wkbPolygon)
#Create the fields
fi1 = ogr.FieldDefn("geocode",field_type=ogr.OFTInteger)
dl.CreateField(fi1)
for v in varlist:
#print "creating data fields"
fi = ogr.FieldDefn(v,field_type=ogr.OFTString)
fi.SetPrecision(12)
dl.CreateField(fi)
#Add the features (points)
for n,l in enumerate(data):
#Iterate over the lines of the data matrix.
gc = l[0]
try:
geom = self.geomdict[gc]
if geom.GetGeometryType() != 3: continue
#print geom.GetGeometryCount()
fe = ogr.Feature(dl.GetLayerDefn())
fe.SetField('geocode',gc)
for v,d in zip (varlist,l[1:]):
#print v,d
fe.SetField(v,str(d))
#Add the geometry
#print "cloning geometry"
clone = geom.Clone()
#print geom
#print "setting geometry"
fe.SetGeometry(clone)
#print "creating geom"
dl.CreateFeature(fe)
except: #Geocode not in polygon dictionary
pass
dl.SyncToDisk()
como tenho todas as geometrias em um dicionário por geocode (self.geomdict), simplesmente crio os recursos, defino os campos e clono as geometrias da camada pré-existente (o carregamento de código dessa camada foi omitido por simplicidade). Tudo o que preciso agora é uma maneira de gerar o GeoJSON a partir da combinação de campos e geometrias, naturalmente com a ajuda do OGR para corrigir o restante do arquivo (CRS, etc. a partir do mapa de origem)
Como exportar a coleção de recursos gerada como acima?
fe.ExportToJson()
retorna uma string, então você precisa se envolverjson.loads(...)
. Caso contrário, isso é super útil!Se você possui um ambiente de desenvolvimento GDAL / OGR (cabeçalhos, bibliotecas), pode simplificar radicalmente seu código usando Fiona . Para ler os recursos de um shapefile, adicione novos atributos e escreva-os, pois o GeoJSON é apenas um punhado de linhas:
fonte
Este é o mais simples e fácil de Fiona. você pode definir o SRS para a saída GeoJSON.
fonte