GDAL을 사용하여 특정 위도 / 경도 위치로 이미지를 생성 하시겠습니까?


9

위도, 경도 및 data_val 형식의 ASCII 파일이 다음 형식으로 있습니다.

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

GeoTiff 이미지 파일이 있는데 쉽게 볼 수 있습니다.

ASCII 파일에서 찾은 특정 위도 / 경도 위치에 이미지에 "핀"(점 / 플래그 / 별 또는 가장 쉬운 것)을 배치하고 싶습니다.

지금까지 내가 관리 한 것은 다음과 같습니다.

내 소스 이미지는 다음과 같습니다.

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
...

다음은 파이썬에서 함께 모은 것입니다.

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

그러나 35-13.643782N, 080-57.190157W에 "빨간색 점"을 배치하는 방법을 알 수는 없습니다.

나는 여기에서 새로운 세부 사항을 배워야합니다 (GIS에 대한 명명법).


조사해야 할 주제는 지리 참조입니다.
PolyGeo

감사합니다 .. 지리 참조라는 용어를 사용하여 Google 검색을 수행했습니다. 도움이되었습니다. 절반 전투는 사용에 어떤 기술 용어를 알고있다 ..
브래드 워커

누락 된 것이 확실하지만 데이터를 KML 또는 다른 것으로 변환하는 것을 고려한 적이 있습니까?
barrycarter

1
DD-MM.mmmmH 좌표를 십진수로 변환해야 할 수도 있습니다. 반구 정보를 분석해야합니다. W 또는 S는 음수 값을 의미합니다 (마지막 단계로 수행). 분은 60으로 나누고도 부분에 추가하거나 연결해야합니다.
mkennedy 2016

답변:


7

귀하의 gdalinfo출력을 보여줍니다 당신은 색상 표 (AKA 팔레트) 단일 밴드 GeoTIFF 있습니다. 해당 색상 표의 값을 볼 수 없으므로 아래 명령은 단일 대역 + 색상 표를 3 대역 RGB GeoTIFF로 변환합니다. 이 명령은 ASCII 파일에 헤더 행이 있고 10 진수로 좌표가 있다고 가정합니다. 그렇지 않은 경우 파일을 수정해야 할 수도 있습니다.

입력 :

$ 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

방법:

$ 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

마지막 명령은 다음을 수행합니다.

  • Lon / Lat 포인트를 더 큰 다각형으로 버퍼링하여 더 잘 표시됩니다 (빨간색의 단일 픽셀 만 원한다면 건너 뛸 수 있습니다)
  • WGS84 Lat / Lon (EPSG : 4326)에서 래스터와 동일한 좌표계로 변환 (EPS : 32754, WGS 84 UTM Zone 54S, CRS가 다름)
  • 출력 폴리곤을 GeoJSON으로 STDOUT에 작성하고 파이프에 gdal_rasterize
  • RGB 255,0,0을 RGB 래스터 밴드 1, 2 및 3에 레코딩

결과:

여기에 이미지 설명을 입력하십시오


3

당신은 좋은 시작을했습니다. gdal.CreateCopy지리 참조를 처리하므로 지오 변환 및 투영을 사용하여 두 번째로 설정할 필요가 없습니다.

전체 프로세스는 lon / lat 좌표를 래스터 공간 참조의 XY 좌표로 변환합니다. 그런 다음이 XY 좌표는 역 지오 변형을 사용하여 래스터의 열, 열 인덱스로 변환됩니다. 해당 위치에 일부 픽셀 값이 기록됩니다.

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

참고 1 :

명령 gdal.RasterBand.WriteArray(array, xoff, yoff)은 왼쪽 상단에서 작동합니다. 이 예에서는 값 255는 1x1 배열을 제공하기 때문에, xoff그리고 yoff실제 행의 경도 / 위도 포지션 COL 인덱스이다. 당신은 3 × 3 사각형을 작성하려는 경우, 당신은 조정해야 xoff하고 yoff1을 빼서 당신은 또한 확실히 배열 데이터 형식 래스터의 일치해야합니다. "빨간색 점"을 원한다고했기 때문에 uint8의 3 개의 밴드가 있다고 가정합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.