Tạo hình ảnh với các vị trí vĩ độ / kinh độ cụ thể bằng GDAL?


9

Tôi có tệp ASCII với vĩ độ, kinh độ và data_val theo định dạng sau.

35-13.643782N, 080-57.190157W, 118.6
...

Tôi có tệp hình ảnh GeoTiff và tôi có thể dễ dàng xem nó.

Tôi muốn đặt một "pin" (có thể là dấu chấm / cờ / sao hoặc bất cứ thứ gì dễ nhất) trên hình ảnh ở vị trí vĩ độ / kinh độ cụ thể được tìm thấy trong tệp ASCII.

Đây là những gì tôi đã quản lý để làm cho đến nay:

Hình ảnh nguồn của tôi trông như thế này:

Driver: GTiff/GeoTIFF
Files: /tmp/Charlotte SEC 100.tif
Size is 16867, 12358
Coordinate System is:
PROJCS["Lambert Conformal Conic",
    GEOGCS["NAD83",
        DATUM["North_American_Datum_1983",
            SPHEROID["GRS 1980",6378137,298.2572221010042,
                AUTHORITY["EPSG","7019"]],
            AUTHORITY["EPSG","6269"]],
        PRIMEM["Greenwich",0],
        UNIT["degree",0.0174532925199433],
        AUTHORITY["EPSG","4269"]],
    PROJECTION["Lambert_Conformal_Conic_2SP"],
    PARAMETER["standard_parallel_1",38.66666666666666],
    PARAMETER["standard_parallel_2",33.33333333333334],
    PARAMETER["latitude_of_origin",34.11666666666667],
    PARAMETER["central_meridian",-78.75],
    PARAMETER["false_easting",0],
    PARAMETER["false_northing",0],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]]]
Origin = (-365041.822331817995291,240536.419747152860509)
Pixel Size = (42.334586069440391,-42.334898968590878)
Metadata:
  AREA_OR_POINT=Area
  TIFFTAG_DATETIME=2016:06:24 12:46:45
  TIFFTAG_RESOLUTIONUNIT=2 (pixels/inch)
  TIFFTAG_SOFTWARE=Adobe Photoshop CS5 Windows
  TIFFTAG_XRESOLUTION=300
  TIFFTAG_YRESOLUTION=300
Image Structure Metadata:
  COMPRESSION=LZW
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  ( -365041.822,  240536.420) ( 82d48'55.43"W, 36d13' 4.92"N)
Lower Left  ( -365041.822, -282638.262) ( 82d35'10.11"W, 31d30'17.00"N)
Upper Right (  349015.641,  240536.420) ( 74d51'46.40"W, 36d13'26.16"N)
Lower Right (  349015.641, -282638.262) ( 75d 4'55.60"W, 31d30'36.99"N)
Center      (   -8013.091,  -21050.921) ( 78d50'12.11"W, 33d55'36.35"N)
Band 1 Block=16867x1 Type=Byte, ColorInterp=Palette
  Color Table (RGB with 256 entries)
    0: 255,255,255,255
...

Đây là những gì tôi đã quản lý để ghép lại với nhau trong Python:

from osgeo import gdal, osr

src_filename = '/tmp/Charlotte SEC 100.tif'
dst_filename = '/tmp/foo.tiff'

# Opens source dataset
src_ds = gdal.Open(src_filename)
format = "GTiff"
driver = gdal.GetDriverByName(format)

# Open destination dataset
dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

# Specify raster location through geotransform array
# (upperleftx, scalex, skewx, upperlefty, skewy, scaley)
# Scale = size of one pixel in units of raster projection
# this example below assumes 100x100
gt = [-365041.822, 100, 0, 240536.420, 0, -100]

# Set location
dst_ds.SetGeoTransform(gt)

# Get raster projection
epsg = 4269            # http://spatialreference.org/ref/sr-org/lambert_conformal_conic_2sp/
srs = osr.SpatialReference()
srs.ImportFromEPSG(epsg)
dest_wkt = srs.ExportToWkt()

# Set projection
dst_ds.SetProjection(dest_wkt)

# Close files
dst_ds = None
src_ds = None

Nhưng, tôi hoàn toàn không thể tìm ra cách đặt "chấm đỏ" ở 35-13,643782N, 080-57.190157W

Tôi phải tìm hiểu một số chi tiết mới ở đây (danh pháp về GIS).


Chủ đề bạn có thể cần điều tra là Georeferences.
PolyGeo

Cảm ơn .. Tôi đã thực hiện một số tìm kiếm trên Google bằng thuật ngữ Georeferences. Điều đó rất hữu ích. Một nửa trận chiến là biết sử dụng thuật ngữ kỹ thuật nào ..
Brad Walker

Tôi chắc chắn rằng tôi đang thiếu một cái gì đó, nhưng bạn đã xem xét chuyển đổi dữ liệu sang KML hay gì chưa?
barrycarter

1
Bạn có thể cần phải chuyển đổi tọa độ DD-MM.mmmmH của mình thành độ thập phân. Bạn sẽ cần phân tích thông tin Bán cầu W hoặc S có nghĩa là một giá trị âm (làm điều đó như bước cuối cùng). Biên bản cần được chia cho 60 và thêm hoặc nối với phần độ.
mkennedy

Câu trả lời:


7

gdalinfoĐầu ra của bạn cho thấy bạn có một dải GeoTIFF với một bảng màu (bảng màu AKA). Tôi không thể thấy các giá trị trong bảng màu đó để các lệnh bên dưới chuyển đổi bảng màu đơn + bảng thành ba dải GeoTIFF ba dải. Các lệnh cũng giả sử tệp ASCII của bạn có một hàng tiêu đề và có tọa độ theo độ thập phân, bạn có thể cần phải sửa đổi tệp của mình nếu không.

Đầu vào:

$ cat testlonlat.csv
LON,LAT
143.798425,-15.551485
143.827437,-15.535119
143.84561,-15.530017
143.859107,-15.54819
143.812347,-15.523641
143.853581,-15.534694
143.883337,-15.537669
143.885356,-15.561687
143.887694,-15.588468

$ gdalinfo testutm.tif
Driver: GTiff/GeoTIFF
Files: testutm.tif
Size is 1102, 959
Coordinate System is:
PROJCS["WGS 84 / UTM zone 54S",
    GEOGCS["WGS 84",
        DATUM["WGS_1984",
            SPHEROID["WGS 84",6378137,298.257223563,
                AUTHORITY["EPSG","7030"]],
            AUTHORITY["EPSG","6326"]],
        PRIMEM["Greenwich",0,
            AUTHORITY["EPSG","8901"]],
        UNIT["degree",0.0174532925199433,
            AUTHORITY["EPSG","9122"]],
        AUTHORITY["EPSG","4326"]],
    PROJECTION["Transverse_Mercator"],
    PARAMETER["latitude_of_origin",0],
    PARAMETER["central_meridian",141],
    PARAMETER["scale_factor",0.9996],
    PARAMETER["false_easting",500000],
    PARAMETER["false_northing",10000000],
    UNIT["metre",1,
        AUTHORITY["EPSG","9001"]],
    AXIS["Easting",EAST],
    AXIS["Northing",NORTH],
    AUTHORITY["EPSG","32754"]]
Origin = (798741.168775000027381,8282084.855279999785125)
Pixel Size = (10.000000000000000,-10.000000000000000)
Metadata:
  AREA_OR_POINT=Area
Image Structure Metadata:
  INTERLEAVE=BAND
Corner Coordinates:
Upper Left  (  798741.169, 8282084.855) (143d47' 4.96"E, 15d31'16.22"S)
Lower Left  (  798741.169, 8272494.855) (143d47' 9.15"E, 15d36'27.98"S)
Upper Right (  809761.169, 8282084.855) (143d53'14.43"E, 15d31'11.47"S)
Lower Right (  809761.169, 8272494.855) (143d53'18.78"E, 15d36'23.20"S)
Center      (  804251.169, 8277289.855) (143d50'11.83"E, 15d33'49.74"S)
Band 1 Block=1102x7 Type=Byte, ColorInterp=Palette
  Color Table (RGB with 256 entries)
    0: 120,112,136,255
    1: 96,104,88,255
    ...
    254: 76,124,140,255
    255: 232,228,236,255

Quá trình:

$ gdal_translate -expand rgb testutm.tif testutm_rgb.tif

$ ogr2ogr -f "GeoJSON" -dialect sqlite                      \
  -sql "select ST_buffer(Geometry,0.001) from testlonlat"   \
  -s_srs EPSG:4326 -t_srs EPSG:32754                        \
  /vsistdout/ CSV:testlonlat.csv -oo X_POSSIBLE_NAMES=Lon   \
  -oo Y_POSSIBLE_NAMES=Lat |  gdal_rasterize -b 1 -b 2 -b 3 \
  -burn 255 -burn 0 -burn 0 /vsistdin/ testutm_rgb.tif

Lệnh cuối cùng thực hiện như sau:

  • đệm điểm Lon / Lat vào một đa giác lớn hơn để nó hiển thị tốt hơn (bạn có thể bỏ qua điều đó nếu bạn chỉ muốn một pixel màu đỏ)
  • chuyển đổi từ WGS84 Lat / Lon (EPSG: 4326) sang cùng hệ thống tọa độ với raster (EPSG: 32754 là WGS 84 UTM Vùng 54S, CRS của bạn sẽ khác)
  • ghi đa giác đầu ra dưới dạng GeoJSON vào STDOUT và chuyển nó sang gdal_rasterize
  • ghi RGB 255,0,0 vào các dải raster RGB 1, 2 & 3

Kết quả:

nhập mô tả hình ảnh ở đây


3

Bạn có một khởi đầu tốt. gdal.CreateCopysẽ quan tâm đến hội nghị địa lý, do đó bạn không phải đặt lần thứ hai bằng cách sử dụng geotransform và phép chiếu.

Quá trình hoàn chỉnh sẽ biến đổi các cuộn dây lon / lat thành tọa độ XY của tham chiếu không gian raster. Sau đó, các cuộn XY này sẽ được chuyển thành hàng, chỉ số col của raster bằng cách sử dụng geotransform nghịch đảo. Một số giá trị pixel sẽ được viết tại vị trí đó.

from osgeo import gdal, osr
import numpy as np

src_filename = '/tmp/Charlotte SEC 100.tif'
dst_filename = '/tmp/foo.tiff'

# Opens source dataset
src_ds = gdal.Open(src_filename)
format = "GTiff"
driver = gdal.GetDriverByName(format)

# Open destination dataset
dst_ds = driver.CreateCopy(dst_filename, src_ds, 0)

# Get raster projection
epsg = 4269         # http://spatialreference.org/ref/sr-org/lambert_conformal_conic_2sp/
srs = osr.SpatialReference()
srs.ImportFromEPSG(epsg)

# Make WGS84 lon lat coordinate system
world_sr = osr.SpatialReference()
world_sr.SetWellKnownGeogCS('WGS84')

# Transform lon lats into XY
lonlat = [[0.,30.], [20., 30.], [25., 30.]]
coord_transform = osr.CoordinateTransformation(world_sr, srs)
newpoints = coord_transform.TransformPoints(lonlat) # list of XYZ tuples

# Make Inverse Geotransform  (try:except due to gdal version differences)
try:
    success, inverse_gt = gdal.InvGeoTransform(gt)
except:
    inverse_gt = gdal.InvGeoTransform(gt)

# [Note 1] Set pixel values
marker_array_r = np.array([[255]], dtype=np.uint8)
marker_array_g = np.array([[0]], dtype=np.uint8)
marker_array_b = np.array([[0]], dtype=np.uint8)
for x,y,z in newpoints:
    pix_x = int(inverse_gt[0] + inverse_gt[1] * x + inverse_gt[2] * y)
    pix_y = int(inverse_gt[3] + inverse_gt[4] * x + inverse_gt[5] * y)
    dst_ds.GetRasterBand(1).WriteArray(marker_array_r, pix_x, pix_y)
    dst_ds.GetRasterBand(2).WriteArray(marker_array_g, pix_x, pix_y)
    dst_ds.GetRasterBand(3).WriteArray(marker_array_b, pix_x, pix_y)

# Close files
dst_ds = None
src_ds = None

Lưu ý 1:

Lệnh gdal.RasterBand.WriteArray(array, xoff, yoff)hoạt động từ góc trên bên trái. Trong ví dụ này tôi cung cấp một mảng 1x1 với giá trị 255, xoffyofflà hàng thực tế, chỉ số col cho vị trí lon / lat. Nếu bạn muốn viết một hình vuông 3x3, bạn cần điều chỉnh xoffyofftrừ đi 1. Bạn cũng nên đảm bảo kiểu dữ liệu mảng khớp với raster. Bởi vì bạn nói rằng bạn muốn có một "chấm đỏ", tôi giả sử có ba dải uint8.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.