def test_point_to_pixel_geometry(self): '''Should correctly calculate pixel geometry from center points.''' ds = gdal.Open(os.path.join(self.test_dir, 'multi3_raster.tiff')) xy_coords = pixel_to_xy([[10, 10], [20, 20]], ds.GetGeoTransform(), ds.GetProjection()) geometries = point_to_pixel_geometry(xy_coords, source_epsg = 32617, target_epsg=4326) self.assertTrue(isinstance(geometries[0], ogr.Geometry)) self.assertEqual(geometries[0].ExportToWkt(), 'POLYGON ((-84.8920166606528 42.4576139546101 0,-84.8916526360905 42.4576263335341 0,-84.8916359196253 42.457356779353 0,-84.8919999426335 42.4573444005452 0,-84.8920166606528 42.4576139546101 0))') self.assertEqual(geometries[1].ExportToWkt(), 'POLYGON ((-84.5128222586605 42.1997431501765 0,-84.5124595623182 42.1997542699897 0,-84.5124446081078 42.1994845879707 0,-84.5128073029137 42.1994734682621 0,-84.5128222586605 42.1997431501765 0))')
def test_point_to_pixel_geometry(self): '''Should correctly calculate pixel geometry from center points.''' ds = gdal.Open(os.path.join(self.test_dir, 'multi3_raster.tiff')) xy_coords = pixel_to_xy([[10, 10], [20, 20]], ds.GetGeoTransform(), ds.GetProjection()) geometries = point_to_pixel_geometry(xy_coords, source_epsg=32617, target_epsg=4326) self.assertTrue(isinstance(geometries[0], ogr.Geometry)) self.assertEqual( geometries[0].ExportToWkt(), 'POLYGON ((-84.89202 42.45761 0,-84.89165 42.45763 0,-84.89164 42.45736 0,-84.892 42.45734 0,-84.89202 42.45761 0))' ) self.assertEqual( geometries[1].ExportToWkt(), 'POLYGON ((-84.51282 42.19974 0,-84.51246 42.19975 0,-84.51244 42.19948 0,-84.51281 42.19947 0,-84.51282 42.19974 0))' )
def on_draw(self, output_dir=None): def get_data_in_selection(c1, c2): condition = np.logical_and(c1, c2).reshape(shp2) # Get the X and Y pixel coordinates within the bounding boxes cx = ravel_and_filter(np.where(condition, xdata, nodata_array).T, nodata=self.__nodata__) cy = ravel_and_filter(np.where(condition, ydata, nodata_array).T, nodata=self.__nodata__) # Zip the X and Y arrays into an X,Y array # NOTE: We flip the Y and X here because the `xdata` are column # indices and `ydata` are row indices, but as pixel coordinates # the row number is a Y-axis cordinate, column number is # an X-axis coordinate return np.dstack((cy[:, 0], cx[:, 0])) shp = self.features.shape shp2 = (shp[0], shp[1], 1) # Shape for a single band # Array of X coordinates xdata = np.repeat([np.arange(0, shp[1])], shp[0], axis=0).reshape(shp2) # Array of Y coordinates ydata = np.repeat([np.arange(0, shp[0])], shp[1], axis=0).T.reshape(shp2) nodata_array = np.ones(shp2) * self.__nodata__ # Make NoData array tmp = self.features.reshape((shp[0] * shp[1], shp[-1])) # Start with top-left, end with bottom-right if self.x0 < self.x1: if self.y0 > self.y1: selection = get_data_in_selection( np.logical_and(tmp[:, 0] > self.x0, tmp[:, 1] < self.y0), np.logical_and(tmp[:, 0] < self.x1, tmp[:, 1] > self.y1)) # Start with bottom-left, end with top-right else: selection = get_data_in_selection( np.logical_and(tmp[:, 0] > self.x0, tmp[:, 1] > self.y0), np.logical_and(tmp[:, 0] < self.x1, tmp[:, 1] < self.y1)) # Start with bottom-right, end with top-left else: if self.y0 < self.y1: selection = get_data_in_selection( np.logical_and(tmp[:, 0] < self.x0, tmp[:, 1] > self.y0), np.logical_and(tmp[:, 0] > self.x1, tmp[:, 1] < self.y1)) # Start with top-right, end with bottom-left else: selection = get_data_in_selection( np.logical_and(tmp[:, 0] < self.x0, tmp[:, 1] < self.y0), np.logical_and(tmp[:, 0] > self.x1, tmp[:, 1] > self.y1)) # Limit to N random features if selection.shape[1] >= self.__sel_limit__: rfeatures = np.random.choice(np.arange(0, selection.shape[1]), size=self.__sel_limit__, replace=False) rfeatures.sort( ) # Make it easier to get iterate through them in order selection = selection[:, rfeatures, :] file_path = os.path.join( (output_dir or self.__wd__), 'FeatureSpace_selection_%s_%d' % ((self.keyword or ''), self.__drawing_index__)) points = pixel_to_xy(selection[0, :], self.__gt__, self.__wkt__, dd=False) points_dd = pixel_to_xy(selection[0, :], self.__gt__, self.__wkt__, dd=True) # If a source EPSG is known, convert the output to KML if self.epsg is not None: # Convert to WGS 84 poly_geom = point_to_pixel_geometry(points, source_epsg=self.epsg, target_epsg=4326) # We want to create Placemarks with both a Point and # a Polygon geometry in each pmarks = [] for i, poly in enumerate(poly_geom): pm = KML_POLY_TEMPLATE % ( ','.join(map(str, points[i])), # The (projected) coordinates '<Point><coordinates>%f,%f</coordinates></Point>' % points_dd[i], poly.ExportToKML() # The KML Polygon feature ) pmarks.append(pm) doc = KML_DOC_TEMPLATE % (KML_POLY_STYLE, ''.join(pmarks)) # Write out the coordinates as a KML file with open('%s.kml' % file_path, 'w') as stream: stream.write(doc) if self.__verbose__: sys.stdout.write( "Wrote selection's coordinates in geographic space to: %s.kml\n" % file_path) else: sys.stdout.write( "Warning: Source SRS not known; cannot output KML file\n")