Input GeoJSON file:
{
"type": "Feature",
"properties": {
"id": 1
},
"geometry": {
"type": "Multipolygon",
"coordinates": [[[
[27.397511483867362, 44.161117466010516],
[27.393924221672666, 44.159751598403503],
[27.393556666460618, 44.159252063395591],
[27.393726740035870, 44.158373985750522],
[27.392040835956994, 44.157378400690988],
[27.390354358253163, 44.156239034941315],
[27.390977924658255, 44.152849194060536],
[27.391438333095618, 44.149298658002031],
[27.386781918912796, 44.147461728155896],
[27.384487250437232, 44.146859408403664],
[27.382636468741264, 44.156671855578281],
[27.383891699721374, 44.156645049015140],
[27.384649769913505, 44.157388133683327],
[27.385547083122507, 44.160232076255667],
[27.387997850095061, 44.160722084482430],
[27.390672446485077, 44.161638147279866],
[27.395361188085396, 44.163429614137918],
[27.396513835695238, 44.162325787855522],
[27.397511483867362, 44.161117466010516]
]]]
}
}
Need to clip geotiff file.
Additional terms:
- I can use only gdal modules (without using any console utilities).
- math, numpy, etc. are welcome
- result image must be like this:
UPDATE:
def crop_by_bounding_box(min_x, max_x, min_y, max_y):
xValues = [min_x, max_x]
yValues = [min_y, max_y]
#
# Register Imagine driver and open file
#
driver = gdal.GetDriverByName('GTiff')
driver.Register()
dataset = gdal.Open(filename + '.tif')
if dataset is None:
print 'Could not open ' + filename + '.tif'
sys.exit(1)
#
# Getting image dimensions
#
cols = dataset.RasterXSize
rows = dataset.RasterYSize
bands = dataset.RasterCount
#
# Getting georeference info
#
transform = dataset.GetGeoTransform()
xOrigin = transform[0]
yOrigin = transform[3]
pixelWidth = transform[1]
pixelHeight = -transform[5]
#
# Computing Point1(i1,j1), Point2(i2,j2)
#
i1 = int((xValues[0] - xOrigin) / pixelWidth)
j1 = int((yOrigin - yValues[0]) / pixelHeight)
i2 = int((xValues[1] - xOrigin) / pixelWidth)
j2 = int((yOrigin - yValues[1]) / pixelHeight)
new_cols = i2 - i1 + 1
new_rows = j2 - j1 + 1
#
# Create list to store band data in
#
band_list = []
#
# Read in bands and store all the data in bandList
#
for i in range(bands):
band = dataset.GetRasterBand(i+1) # 1-based index
data = band.ReadAsArray(i1, j1, new_cols, new_rows)
band_list.append(data)
new_x = xOrigin + i1 * pixelWidth
new_y = yOrigin - j1 * pixelHeight
new_transform = (new_x, transform[1], transform[2], new_y, transform[4], transform[5])
#
# Create gtif file
#
driver = gdal.GetDriverByName("GTiff")
dst_ds = driver.Create(output_file, new_cols, new_rows, 3, gdal.GDT_Byte)
#
# Writting output raster
#
for j in range(bands):
data = band_list[j]
dst_ds.GetRasterBand(j+1).WriteArray(data)
#
# Setting extension of output raster
#
dst_ds.SetGeoTransform(new_transform)
wkt = dataset.GetProjection()
#
# Setting spatial reference of output raster
#
srs = osr.SpatialReference()
srs.ImportFromWkt(wkt)
dst_ds.SetProjection( srs.ExportToWkt() )
#
# Close output raster dataset
#
dataset = None
dst_ds = None
def crop_by_geojson(geojson):
# extract the geometry
geom = geojson['geometry']
# convert to json string for ogr
geom_str = json.dumps(geom)
# create the ogr geometry
geom_ogr = ogr.CreateGeometryFromJson(geom_str)
# export to wkt
geom_ogr.ExportToWkt()
#lat_lon_to_utm(lat, lon)
min_x, max_x, min_y, max_y = bbox(geojson)
print min_x, max_x, min_y, max_y
XYmin = lat_lon_to_utm(max_y, min_x)
XYmax = lat_lon_to_utm(min_y, max_x)
crop_by_bounding_box(XYmin[0], XYmax[0], XYmin[1], XYmax[1])
Code to explode a GeoJSON geometry's coordinates object and yield coordinate tuples:
def explode(coords):
for e in coords:
if isinstance(e, (float, int, long)):
yield coords
break
else:
for f in explode(e):
yield f
a, b = zip(*list(explode(geojson['geometry']['coordinates'])))
But anyway I'm stuck with cutting. This way doesn't work. I have an error:
clip = gdalnumeric.choose(mask, (clip, 0)).astype(gdalnumeric.uint8)
ValueError: shape mismatch: objects cannot be broadcast to a single shape
