青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

GDAL API Tutorial

http://www.gdal.org/gdal_tutorial.html

Opening the File

Before opening a GDAL supported raster datastore it is necessary to register drivers. There is a driver for each supported format. Normally this is accomplished with the GDALAllRegister() function which attempts to register all known drivers, including those auto-loaded from .so files using GDALDriverManager::AutoLoadDrivers(). If for some applications it is necessary to limit the set of drivers it may be helpful to review the code from gdalallregister.cpp.

Once the drivers are registered, the application should call the free standing GDALOpen() function to open a dataset, passing the name of the dataset and the access desired (GA_ReadOnly or GA_Update).

In C++:

#include "gdal_priv.h"
int main()
{
GDALDataset  *poDataset;
GDALAllRegister();
poDataset = (GDALDataset *) GDALOpen( pszFilename, GA_ReadOnly );
if( poDataset == NULL )
{
...;
}

In C:

#include "gdal.h"
int main()
{
GDALDatasetH  hDataset;
GDALAllRegister();
hDataset = GDALOpen( pszFilename, GA_ReadOnly );
if( hDataset == NULL )
{
...;
}

In Python:

    import gdal
from gdalconst import *
dataset = gdal.Open( filename, GA_ReadOnly )
if dataset is None:
...

Note that if GDALOpen() returns NULL it means the open failed, and that an error messages will already have been emitted via CPLError(). If you want to control how errors are reported to the user review the CPLError() documentation. Generally speaking all of GDAL uses CPLError() for error reporting. Also, note that pszFilename need not actually be the name of a physical file (though it usually is). It's interpretation is driver dependent, and it might be an URL, a filename with additional parameters added at the end controlling the open or almost anything. Please try not to limit GDAL file selection dialogs to only selecting physical files.

Getting Dataset Information

As described in the GDAL Data Model, a GDALDataset contains a list of raster bands, all pertaining to the same area, and having the same resolution. It also has metadata, a coordinate system, a georeferencing transform, size of raster and various other information.

    adfGeoTransform[0] /* top left x */
adfGeoTransform[1] /* w-e pixel resolution */
adfGeoTransform[2] /* rotation, 0 if image is "north up" */
adfGeoTransform[3] /* top left y */
adfGeoTransform[4] /* rotation, 0 if image is "north up" */
adfGeoTransform[5] /* n-s pixel resolution */

If we wanted to print some general information about the dataset we might do the following:

In C++:

    double        adfGeoTransform[6];
printf( "Driver: %s/%s\n",
poDataset->GetDriver()->GetDescription(),
poDataset->GetDriver()->GetMetadataItem( GDAL_DMD_LONGNAME ) );
printf( "Size is %dx%dx%d\n",
poDataset->GetRasterXSize(), poDataset->GetRasterYSize(),
poDataset->GetRasterCount() );
if( poDataset->GetProjectionRef()  != NULL )
printf( "Projection is `%s'\n", poDataset->GetProjectionRef() );
if( poDataset->GetGeoTransform( adfGeoTransform ) == CE_None )
{
printf( "Origin = (%.6f,%.6f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
printf( "Pixel Size = (%.6f,%.6f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}

In C:

    GDALDriverH   hDriver;
double        adfGeoTransform[6];
hDriver = GDALGetDatasetDriver( hDataset );
printf( "Driver: %s/%s\n",
GDALGetDriverShortName( hDriver ),
GDALGetDriverLongName( hDriver ) );
printf( "Size is %dx%dx%d\n",
GDALGetRasterXSize( hDataset ),
GDALGetRasterYSize( hDataset ),
GDALGetRasterCount( hDataset ) );
if( GDALGetProjectionRef( hDataset ) != NULL )
printf( "Projection is `%s'\n", GDALGetProjectionRef( hDataset ) );
if( GDALGetGeoTransform( hDataset, adfGeoTransform ) == CE_None )
{
printf( "Origin = (%.6f,%.6f)\n",
adfGeoTransform[0], adfGeoTransform[3] );
printf( "Pixel Size = (%.6f,%.6f)\n",
adfGeoTransform[1], adfGeoTransform[5] );
}

In Python:

    print 'Driver: ', dataset.GetDriver().ShortName,'/', \
dataset.GetDriver().LongName
print 'Size is ',dataset.RasterXSize,'x',dataset.RasterYSize, \
'x',dataset.RasterCount
print 'Projection is ',dataset.GetProjection()
geotransform = dataset.GetGeoTransform()
if not geotransform is None:
print 'Origin = (',geotransform[0], ',',geotransform[3],')'
print 'Pixel Size = (',geotransform[1], ',',geotransform[5],')'

Fetching a Raster Band

At this time access to raster data via GDAL is done one band at a time. Also, there is metadata, blocksizes, color tables, and various other information available on a band by band basis. The following codes fetches a GDALRasterBand object from the dataset (numbered 1 through GetRasterCount()) and displays a little information about it.

In C++:

        GDALRasterBand  *poBand;
int             nBlockXSize, nBlockYSize;
int             bGotMin, bGotMax;
double          adfMinMax[2];
poBand = poDataset->GetRasterBand( 1 );
poBand->GetBlockSize( &nBlockXSize, &nBlockYSize );
printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
nBlockXSize, nBlockYSize,
GDALGetDataTypeName(poBand->GetRasterDataType()),
GDALGetColorInterpretationName(
poBand->GetColorInterpretation()) );
adfMinMax[0] = poBand->GetMinimum( &bGotMin );
adfMinMax[1] = poBand->GetMaximum( &bGotMax );
if( ! (bGotMin && bGotMax) )
GDALComputeRasterMinMax((GDALRasterBandH)poBand, TRUE, adfMinMax);
printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
if( poBand->GetOverviewCount() > 0 )
printf( "Band has %d overviews.\n", poBand->GetOverviewCount() );
if( poBand->GetColorTable() != NULL )
printf( "Band has a color table with %d entries.\n",
poBand->GetColorTable()->GetColorEntryCount() );

In C:

        GDALRasterBandH hBand;
int             nBlockXSize, nBlockYSize;
int             bGotMin, bGotMax;
double          adfMinMax[2];
hBand = GDALGetRasterBand( hDataset, 1 );
GDALGetBlockSize( hBand, &nBlockXSize, &nBlockYSize );
printf( "Block=%dx%d Type=%s, ColorInterp=%s\n",
nBlockXSize, nBlockYSize,
GDALGetDataTypeName(GDALGetRasterDataType(hBand)),
GDALGetColorInterpretationName(
GDALGetRasterColorInterpretation(hBand)) );
adfMinMax[0] = GDALGetRasterMinimum( hBand, &bGotMin );
adfMinMax[1] = GDALGetRasterMaximum( hBand, &bGotMax );
if( ! (bGotMin && bGotMax) )
GDALComputeRasterMinMax( hBand, TRUE, adfMinMax );
printf( "Min=%.3fd, Max=%.3f\n", adfMinMax[0], adfMinMax[1] );
if( GDALGetOverviewCount(hBand) > 0 )
printf( "Band has %d overviews.\n", GDALGetOverviewCount(hBand));
if( GDALGetRasterColorTable( hBand ) != NULL )
printf( "Band has a color table with %d entries.\n",
GDALGetColorEntryCount(
GDALGetRasterColorTable( hBand ) ) );

In Python (note several bindings are missing):

        band = dataset.GetRasterBand(1)
print 'Band Type=',gdal.GetDataTypeName(band.DataType)
min = band.GetMinimum()
max = band.GetMaximum()
if min is None or max is None:
(min,max) = band.ComputeRasterMinMax(1)
print 'Min=%.3f, Max=%.3f' % (min,max)
if band.GetOverviewCount() > 0:
print 'Band has ', band.GetOverviewCount(), ' overviews.'
if not band.GetRasterColorTable() is None:
print 'Band has a color table with ', \
band.GetRasterColorTable().GetCount(), ' entries.'

Reading Raster Data

There are a few ways to read raster data, but the most common is via the GDALRasterBand::RasterIO() method. This method will automatically take care of data type conversion, up/down sampling and windowing. The following code will read the first scanline of data into a similarly sized buffer, converting it to floating point as part of the operation.

In C++:

        float *pafScanline;
int   nXSize = poBand->GetXSize();
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
poBand->RasterIO( GF_Read, 0, 0, nXSize, 1,
pafScanline, nXSize, 1, GDT_Float32,
0, 0 );

In C:

        float *pafScanline;
int   nXSize = GDALGetRasterBandXSize( hBand );
pafScanline = (float *) CPLMalloc(sizeof(float)*nXSize);
GDALRasterIO( hBand, GF_Read, 0, 0, nXSize, 1,
pafScanline, nXSize, 1, GDT_Float32,
0, 0 );

In Python:

        scanline = band.ReadRaster( 0, 0, band.XSize, 1, \
band.XSize, 1, GDT_Float32 )

Note that the returned scanline is of type string, and contains xsize*4 bytes of raw binary floating point data. This can be converted to Python values using the struct module from the standard library:

        import struct
tuple_of_floats = struct.unpack('f' * b2.XSize, scanline)

The RasterIO call takes the following arguments.

CPLErr GDALRasterBand::RasterIO( GDALRWFlag eRWFlag,
int nXOff, int nYOff, int nXSize, int nYSize,
void * pData, int nBufXSize, int nBufYSize,
GDALDataType eBufType,
int nPixelSpace,
int nLineSpace )

Note that the same RasterIO() call is used to read, or write based on the setting of eRWFlag (either GF_Read or GF_Write). The nXOff, nYOff, nXSize, nYSize argument describe the window of raster data on disk to read (or write). It doesn't have to fall on tile boundaries though access may be more efficient if it does.

The pData is the memory buffer the data is read into, or written from. It's real type must be whatever is passed as eBufType, such as GDT_Float32, or GDT_Byte. The RasterIO() call will take care of converting between the buffer's data type and the data type of the band. Note that when converting floating point data to integer RasterIO() rounds down, and when converting source values outside the legal range of the output the nearest legal value is used. This implies, for instance, that 16bit data read into a GDT_Byte buffer will map all values greater than 255 to 255, the data is not scaled!

The nBufXSize and nBufYSize values describe the size of the buffer. When loading data at full resolution this would be the same as the window size. However, to load a reduced resolution overview this could be set to smaller than the window on disk. In this case the RasterIO() will utilize overviews to do the IO more efficiently if the overviews are suitable.

The nPixelSpace, and nLineSpace are normally zero indicating that default values should be used. However, they can be used to control access to the memory data buffer, allowing reading into a buffer containing other pixel interleaved data for instance.

Closing the Dataset

Please keep in mind that GDALRasterBand objects are owned by their dataset, and they should never be destroyed with the C++ delete operator. GDALDataset's can be closed by calling GDALClose() (it is NOT recommended to use the delete operator on a GDALDataset for Windows users because of known issues when allocating and freeing memory across module boundaries. See the relevant topic on the FAQ). Calling GDALClose will result in proper cleanup, and flushing of any pending writes. Forgetting to call GDALClose on a dataset opened in update mode in a popular format like GTiff will likely result in being unable to open it afterwards.

Techniques for Creating Files

New files in GDAL supported formats may be created if the format driver supports creation. There are two general techniques for creating files, using CreateCopy() and Create(). The CreateCopy method involves calling the CreateCopy() method on the format driver, and passing in a source dataset that should be copied. The Create method involves calling the Create() method on the driver, and then explicitly writing all the metadata, and raster data with separate calls. All drivers that support creating new files support the CreateCopy() method, but only a few support the Create() method.

To determine if a particular format supports Create or CreateCopy it is possible to check the DCAP_CREATE and DCAP_CREATECOPY metadata on the format driver object. Ensure that GDALAllRegister() has been called before calling GetDriverByName(). In this example we fetch a driver, and determine whether it supports Create() and/or CreateCopy().

In C++:

#include "cpl_string.h"
...
const char *pszFormat = "GTiff";
GDALDriver *poDriver;
char **papszMetadata;
poDriver = GetGDALDriverManager()->GetDriverByName(pszFormat);
if( poDriver == NULL )
exit( 1 );
papszMetadata = poDriver->GetMetadata();
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
printf( "Driver %s supports Create() method.\n", pszFormat );
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
printf( "Driver %s supports CreateCopy() method.\n", pszFormat );

In C:

#include "cpl_string.h"
...
const char *pszFormat = "GTiff";
GDALDriverH hDriver = GDALGetDriverByName( pszFormat );
char **papszMetadata;
if( hDriver == NULL )
exit( 1 );
papszMetadata = GDALGetMetadata( hDriver, NULL );
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATE, FALSE ) )
printf( "Driver %s supports Create() method.\n", pszFormat );
if( CSLFetchBoolean( papszMetadata, GDAL_DCAP_CREATECOPY, FALSE ) )
printf( "Driver %s supports CreateCopy() method.\n", pszFormat );

In Python:

    format = "GTiff"
driver = gdal.GetDriverByName( format )
metadata = driver.GetMetadata()
if metadata.has_key(gdal.DCAP_CREATE) \
and metadata[gdal.DCAP_CREATE] == 'YES':
print 'Driver %s supports Create() method.' % format
if metadata.has_key(gdal.DCAP_CREATECOPY) \
and metadata[gdal.DCAP_CREATECOPY] == 'YES':
print 'Driver %s supports CreateCopy() method.' % format

Note that a number of drivers are read-only and won't support Create() or CreateCopy().

Using CreateCopy()

The GDALDriver::CreateCopy() method can be used fairly simply as most information is collected from the source dataset. However, it includes options for passing format specific creation options, and for reporting progress to the user as a long dataset copy takes place. A simple copy from the a file named pszSrcFilename, to a new file named pszDstFilename using default options on a format whose driver was previously fetched might look like this:

In C++:

    GDALDataset *poSrcDS =
(GDALDataset *) GDALOpen( pszSrcFilename, GA_ReadOnly );
GDALDataset *poDstDS;
poDstDS = poDriver->CreateCopy( pszDstFilename, poSrcDS, FALSE,
NULL, NULL, NULL );
/* Once we're done, close properly the dataset */
if( poDstDS != NULL )
GDALClose( (GDALDatasetH) poDstDS );
GDALClose( (GDALDatasetH) poSrcDS );

In C:

    GDALDatasetH hSrcDS = GDALOpen( pszSrcFilename, GA_ReadOnly );
GDALDatasetH hDstDS;
hDstDS = GDALCreateCopy( hDriver, pszDstFilename, hSrcDS, FALSE,
NULL, NULL, NULL );
/* Once we're done, close properly the dataset */
if( hDstDS != NULL )
GDALClose( hDstDS );
GDALClose(hSrcDS);

In Python:

    src_ds = gdal.Open( src_filename )
dst_ds = driver.CreateCopy( dst_filename, src_ds, 0 )
    # Once we're done, close properly the dataset
    dst_ds = None
src_ds = None

Note that the CreateCopy() method returns a writeable dataset, and that it must be closed properly to complete writing and flushing the dataset to disk. In the Python case this occurs automatically when "dst_ds" goes out of scope. The FALSE (or 0) value used for the bStrict option just after the destination filename in the CreateCopy() call indicates that the CreateCopy() call should proceed without a fatal error even if the destination dataset cannot be created to exactly match the input dataset. This might be because the output format does not support the pixel datatype of the input dataset, or because the destination cannot support writing georeferencing for instance.

A more complex case might involve passing creation options, and using a predefined progress monitor like this:

In C++:

#include "cpl_string.h"
...
char **papszOptions = NULL;
papszOptions = CSLSetNameValue( papszOptions, "TILED", "YES" );
papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", "PACKBITS" );
poDstDS = poDriver->CreateCopy( pszDstFilename, poSrcDS, FALSE,
papszOptions, GDALTermProgress, NULL );
/* Once we're done, close properly the dataset */
if( poDstDS != NULL )
GDALClose( (GDALDatasetH) poDstDS );
CSLDestroy( papszOptions );

In C:

#include "cpl_string.h"
...
char **papszOptions = NULL;
papszOptions = CSLSetNameValue( papszOptions, "TILED", "YES" );
papszOptions = CSLSetNameValue( papszOptions, "COMPRESS", "PACKBITS" );
hDstDS = GDALCreateCopy( hDriver, pszDstFilename, hSrcDS, FALSE,
papszOptions, GDALTermProgres, NULL );
/* Once we're done, close properly the dataset */
if( hDstDS != NULL )
GDALClose( hDstDS );
CSLDestroy( papszOptions );

In Python:

    src_ds = gdal.Open( src_filename )
dst_ds = driver.CreateCopy( dst_filename, src_ds, 0,
[ 'TILED=YES', 'COMPRESS=PACKBITS' ] )
    # Once we're done, close properly the dataset
    dst_ds = None
src_ds = None

Using Create()

For situations in which you are not just exporting an existing file to a new file, it is generally necessary to use the GDALDriver::Create() method (though some interesting options are possible through use of virtual files or in-memory files). The Create() method takes an options list much like CreateCopy(), but the image size, number of bands and band type must be provided explicitly.

In C++:

    GDALDataset *poDstDS;
char **papszOptions = NULL;
poDstDS = poDriver->Create( pszDstFilename, 512, 512, 1, GDT_Byte,
papszOptions );

In C:

    GDALDatasetH hDstDS;
char **papszOptions = NULL;
hDstDS = GDALCreate( hDriver, pszDstFilename, 512, 512, 1, GDT_Byte,
papszOptions );

In Python:

    dst_ds = driver.Create( dst_filename, 512, 512, 1, gdal.GDT_Byte )

Once the dataset is successfully created, all appropriate metadata and raster data must be written to the file. What this is will vary according to usage, but a simple case with a projection, geotransform and raster data is covered here.

In C++:

    double adfGeoTransform[6] = { 444720, 30, 0, 3751320, 0, -30 };
OGRSpatialReference oSRS;
char *pszSRS_WKT = NULL;
GDALRasterBand *poBand;
GByte abyRaster[512*512];
poDstDS->SetGeoTransform( adfGeoTransform );
oSRS.SetUTM( 11, TRUE );
oSRS.SetWellKnownGeogCS( "NAD27" );
oSRS.exportToWkt( &pszSRS_WKT );
poDstDS->SetProjection( pszSRS_WKT );
CPLFree( pszSRS_WKT );
poBand = poDstDS->GetRasterBand(1);
poBand->RasterIO( GF_Write, 0, 0, 512, 512,
abyRaster, 512, 512, GDT_Byte, 0, 0 );
/* Once we're done, close properly the dataset */
GDALClose( (GDALDatasetH) poDstDS );

In C:

    double adfGeoTransform[6] = { 444720, 30, 0, 3751320, 0, -30 };
OGRSpatialReferenceH hSRS;
char *pszSRS_WKT = NULL;
GDALRasterBandH hBand;
GByte abyRaster[512*512];
GDALSetGeoTransform( hDstDS, adfGeoTransform );
hSRS = OSRNewSpatialReference( NULL );
OSRSetUTM( hSRS, 11, TRUE );
OSRSetWellKnownGeogCS( hSRS, "NAD27" );
OSRExportToWkt( hSRS, &pszSRS_WKT );
OSRDestroySpatialReference( hSRS );
GDALSetProjection( hDstDS, pszSRS_WKT );
CPLFree( pszSRS_WKT );
hBand = GDALGetRasterBand( hDstDS, 1 );
GDALRasterIO( hBand, GF_Write, 0, 0, 512, 512,
abyRaster, 512, 512, GDT_Byte, 0, 0 );
/* Once we're done, close properly the dataset */
GDALClose( hDstDS );

In Python:

    import osr
import numpy
dst_ds.SetGeoTransform( [ 444720, 30, 0, 3751320, 0, -30 ] )
srs = osr.SpatialReference()
srs.SetUTM( 11, 1 )
srs.SetWellKnownGeogCS( 'NAD27' )
dst_ds.SetProjection( srs.ExportToWkt() )
raster = numpy.zeros( (512, 512), dtype=numpy.uint8 )
dst_ds.GetRasterBand(1).WriteArray( raster )
    # Once we're done, close properly the dataset
    dst_ds = None

posted on 2009-04-30 14:39 zmj 閱讀(2409) 評論(0)  編輯 收藏 引用


只有注冊用戶登錄后才能發(fā)表評論。
網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            99re66热这里只有精品4| 亚洲理论电影网| 亚洲欧美在线高清| 亚洲国产高清一区| 亚洲影视在线播放| 亚洲午夜在线| 99精品热视频只有精品10| 亚洲黄色av一区| 亚洲国产日韩精品| 亚洲精品久久| 亚洲欧美一区二区三区极速播放| 亚洲欧洲日产国产综合网| 亚洲高清成人| 亚洲欧洲日本一区二区三区| 亚洲高清三级视频| 欧美成人福利视频| 欧美日韩国产一中文字不卡| 免费欧美视频| 国产精品日韩精品欧美在线| 国产精品一区二区在线观看| 亚洲精品在线一区二区| 亚洲国产精品精华液2区45| 欧美国产日韩免费| 亚洲一区二区少妇| 欧美喷潮久久久xxxxx| 国产一级精品aaaaa看| 另类尿喷潮videofree| 久久蜜桃av一区精品变态类天堂| 久久国产视频网站| 亚洲国产欧美一区| 性做久久久久久久久| 欧美视频免费| 夜夜精品视频| 美女网站在线免费欧美精品| 99精品欧美一区二区三区| 久久久久久自在自线| 亚洲午夜av电影| 久久久亚洲成人| 国产欧美日韩亚洲精品| 一区二区三区黄色| 亚洲卡通欧美制服中文| 欧美另类视频在线| 亚洲三级视频| 亚洲国产精品一区在线观看不卡 | 久久久av毛片精品| 国产一区二区你懂的| 欧美专区18| 麻豆91精品| 99re8这里有精品热视频免费 | 亚洲婷婷免费| 在线观看不卡| 久久一区二区三区国产精品| 亚洲欧美日韩中文视频| 91久久线看在观草草青青| 99视频超级精品| 欧美久久婷婷综合色| 香蕉国产精品偷在线观看不卡| 免费中文字幕日韩欧美| 久久中文在线| 一区二区不卡在线视频 午夜欧美不卡'| 蜜臀久久久99精品久久久久久 | 欧美黄色一区| 欧美色视频一区| 欧美一区二区三区四区视频| 久久久天天操| 久久激情综合| 欧美日韩在线播放| 亚洲欧美视频在线观看视频| 亚洲国产精品高清久久久| 亚洲国产精品第一区二区三区 | 国产精品久久中文| 午夜欧美大尺度福利影院在线看| 欧美日韩精品免费看| 欧美日韩视频在线一区二区观看视频| 一本久久青青| 久久久久久亚洲精品杨幂换脸 | 日韩网站在线| 亚洲人成啪啪网站| 在线视频亚洲| 国产精品毛片在线| 亚洲第一视频| 一区二区电影免费在线观看| 美女日韩在线中文字幕| 在线午夜精品自拍| 欧美日韩国产影院| 日韩午夜高潮| 亚洲国产精品视频一区| 欧美日本中文| 亚洲欧美激情视频| 亚洲欧美国产视频| 今天的高清视频免费播放成人| 久久亚洲影院| 欧美日韩国产一区| 久久综合电影| 欧美日韩亚洲一区二区三区在线观看 | 午夜在线播放视频欧美| 欧美专区第一页| 亚洲人成小说网站色在线| 99re这里只有精品6| 国产一区久久| 欧美成人中文字幕在线| 欧美午夜不卡在线观看免费 | 午夜日韩电影| 国内精品美女av在线播放| 亚洲黄网站在线观看| 欧美精品一区在线观看| 久久久久国产精品厨房| 欧美午夜激情视频| 欧美影院精品一区| 欧美激情精品久久久久久大尺度| 亚洲一区二区av电影| 亚洲欧美在线免费观看| 亚洲人午夜精品| 欧美中文在线字幕| 午夜激情久久久| 欧美激情亚洲自拍| 久久亚裔精品欧美| 亚洲精选91| 91久久在线播放| 久久精品国产免费看久久精品| 亚洲一区二区在线免费观看视频| 嫩模写真一区二区三区三州| 欧美一区二区三区喷汁尤物| 欧美日韩国产一区精品一区| 亚洲国产成人av在线 | 日韩亚洲欧美一区| 久久亚洲捆绑美女| 亚洲四色影视在线观看| 欧美在线一二三四区| 亚洲性视频网址| 久久精品夜夜夜夜久久| 一本色道久久加勒比精品| 欧美性色综合| 亚洲国产一区二区三区在线播| 国产一区二区看久久| 日韩视频一区二区三区在线播放| 亚洲国内欧美| 欧美高清在线播放| 亚洲韩国日本中文字幕| 亚洲高清视频在线| 老司机精品视频一区二区三区| 美女久久网站| 亚洲国产日韩一区二区| 欧美国产日产韩国视频| 亚洲精品1234| 99国产精品私拍| 欧美日韩一区二区在线 | 亚洲精品中文字幕在线| 欧美/亚洲一区| 亚洲成色999久久网站| 在线观看欧美日韩国产| 欧美成人免费网站| 亚洲久久一区二区| 一本色道久久综合亚洲精品高清 | 在线午夜精品| 欧美成人精品高清在线播放| 亚洲国产精品高清久久久| 亚洲靠逼com| 欧美日韩亚洲91| 午夜一区二区三区在线观看| 久久av一区二区三区| 国内一区二区在线视频观看 | 国产深夜精品福利| 香蕉久久久久久久av网站| 久久先锋影音| 亚洲日本国产| 国产精品美女久久久免费| 午夜天堂精品久久久久| 亚洲国产精品悠悠久久琪琪| 亚洲欧美日韩成人| 国内精品久久久久久久97牛牛| 欧美一区二区三区在线看| 亚洲国产日韩欧美综合久久| 亚洲私拍自拍| 韩日午夜在线资源一区二区| 欧美精品免费在线观看| 亚洲视频精品| 久久国产乱子精品免费女| 亚洲肉体裸体xxxx137| 国产欧美三级| 欧美视频导航| 欧美激情影院| 久久男人资源视频| 午夜精品三级视频福利| 亚洲人屁股眼子交8| 裸体女人亚洲精品一区| 亚洲欧美综合一区| 99re8这里有精品热视频免费 | 欧美午夜精品理论片a级按摩| 欧美一级在线播放| 夜夜夜久久久| 亚洲国产日韩欧美在线图片| 久久婷婷国产综合精品青草| 亚洲尤物影院| 中文亚洲欧美| 欧美午夜视频一区二区| 欧美不卡一卡二卡免费版| 久久久久国产免费免费| 午夜国产精品视频免费体验区| 日韩系列在线|