from collections import namedtuple
from django.contrib.gis.gdal import DataSource
import os
import sys
import zipfile
#URL = "http://usfw.labs.ecotrust.org/kmltest/"
URL = "./"
kmz = False
if kmz:
extension = "kmz"
else:
extension = "kml"
test = True
Level = namedtuple('Level',['ds', 'simplify', 'uidfield','parent_uidfield'])
if test:
INDIR = "/home/mperry/subset/input1/"
OUTDIR = "/home/mperry/subset/output1"
URL = "http://a.perrygeo.net/output1/"
LEVELS = [
Level(DataSource(INDIR + 'huc6.shp'), 0.003, 'HUC_6', None),
Level(DataSource(INDIR + 'huc8.shp'), 0.001, 'HUC_8', 'HUC_6'),
Level(DataSource(INDIR + 'huc10.shp'), 0.0001, 'HUC_10', 'HUC8'),
Level(DataSource(INDIR + 'huc12.shp'), 0.00001, 'HUC_12', 'HUC_10'),
]
else:
INDIR = "/home/mperry/subset/input2/"
OUTDIR = "/home/mperry/subset/output2"
LEVELS = [
Level(DataSource(INDIR + 'huc6.shp'), 0.003, 'HUC_6', None),
Level(DataSource(INDIR + 'HUC8_PNW_prj.shp'), 0.001, 'HUC_8', 'HUC_6'),
Level(DataSource(INDIR + 'HUC10_PNW_prj.shp'), 0.0001, 'HUC_10', 'HUC8'),
Level(DataSource(INDIR + 'HUC12.shp'), 0.00001, 'HUC_12', 'HUC_10'),
]
if not os.path.exists(OUTDIR):
os.mkdir(OUTDIR)
kmls = {}
def lfind(needle, haystack):
z=-1
while 1:
try:
z = haystack.index(needle, z+1)
yield z
except:
break
def name_callback(huc):
return "HUC %s" % huc
def desc_callback(huc):
level = len(huc)/2
return "Level %s HUC" % level
def drilldown(levelnum, levels, parent=None):
for levelnum in range(len(levels)):
level = levels[levelnum]
print level
if levelnum < len(levels)-1:
if levelnum == 0:
kmlfile = 'doc.%s' % (extension,)
kmls[kmlfile] = (levelnum, [
{'geom': f.geom,
'uid': f.get(level.uidfield),
'name': name_callback(f.get(level.uidfield)),
'desc': desc_callback(f.get(level.uidfield))
} for f in level.ds[0]])
children_layer = levels[levelnum+1].ds[0]
children_parent_uids = children_layer.get_fields(levels[levelnum+1].parent_uidfield)
for feature in level.ds[0]:
uid = feature.get(level.uidfield)
kmlfile = "%s.%s" % (uid,extension)
child_puidf = levels[levelnum+1].parent_uidfield
child_uidf = levels[levelnum+1].uidfield
indexes = list(lfind(uid,children_parent_uids))
children = []
for i in indexes:
f = children_layer[i]
children.append({
'geom': f.geom,
'uid': f.get(child_uidf),
'name': name_callback(f.get(child_uidf)),
'desc': desc_callback(f.get(child_uidf))
})
kmls[kmlfile] = (levelnum+1, children)
else:
return
def write_kmls(kmls):
kmlhead = """
Watersheds
1
1
"""
kmlfoot = """
"""
netlink = """
%s
%s
%s
%s
%s
356
%s
%s
onRegion
"""
region = """
%s
%s
%s
%s
-1
512
"""
placemark = """
%s
%s
#default
%s
%s
"""
for kmlfile,values in kmls.items():
if not kmz:
fh = open(os.path.join(OUTDIR,kmlfile),'w')
else:
tmpfile = '/tmp/doc.kml'
fh = open(os.path.join(tmpfile),'w')
fh.write(kmlhead)
levelnum, features = values
level = LEVELS[levelnum]
for feature in features:
geom = feature['geom'].transform(4326,clone=True)
uid = feature['uid']
name = feature['name']
desc = feature['desc']
if level.simplify:
geom = geom.geos.simplify(level.simplify)
else:
geom = geom.geos
try:
e = geom.extent
except:
print
print geom
continue
if levelnum == len(LEVELS)-2:
maxlod = "-1"
else:
maxlod = "1450"
placemark_region = ""
if levelnum == 0:
placemark_region = region % (e[0],e[1],e[2],e[3])
if not levelnum == len(LEVELS)-1:
neturl = "%s%s.%s" % (URL,uid,extension)
fh.write(netlink % (uid,
e[0],e[1],e[2],e[3], #bbox
maxlod,
neturl)
)
fh.write(placemark % (name,desc,geom.kml,placemark_region))
fh.write(kmlfoot)
fh.close()
if kmz:
outfile = os.path.join(OUTDIR,kmlfile)
os.chdir('/tmp/')
zip_file = zipfile.ZipFile(outfile, 'w', zipfile.ZIP_DEFLATED)
zip_file.write('doc.kml')
zip_file.close()
if __name__ == "__main__":
kmls = {}
drilldown(0,LEVELS)
print kmls
write_kmls(kmls)